Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 4 additions & 28 deletions App.jsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,11 @@
import { BrowserRouter } from "react-router-dom";
import { NavigationMenu } from "@shopify/app-bridge-react";
import Routes from "./Routes";

import {
AppBridgeProvider,
QueryProvider,
PolarisProvider,
} from "./components";
import { AppRouterProvider, PolarisProvider, QueryProvider } from "./components";

export default function App() {
// Any .tsx or .jsx files in /pages will become a route
// See documentation for <Routes /> for more info
const pages = import.meta.globEager("./pages/**/!(*.test.[jt]sx)*.([jt]sx)");

return (
<PolarisProvider>
<BrowserRouter>
<AppBridgeProvider>
<QueryProvider>
<NavigationMenu
navigationLinks={[
{
label: "Page name",
destination: "/pagename",
},
]}
/>
<Routes pages={pages} />
</QueryProvider>
</AppBridgeProvider>
</BrowserRouter>
<QueryProvider>
<AppRouterProvider />
</QueryProvider>
</PolarisProvider>
);
}
29 changes: 29 additions & 0 deletions components/ErrorBoundary.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Banner, Layout, Page } from "@shopify/polaris";
import { useRouteError } from "react-router-dom";

/**
* ErrorBoundary
* @desc General example error element
*
* See: https://reactrouter.com/en/main/route/error-element
*/

export default function ErrorBoundary() {
const error = useRouteError();

console.error(error);

return (
<Page narrowWidth>
<Layout>
<Layout.Section>
<div style={{ marginTop: "100px" }}>
<Banner title="Something went wrong" status="critical">
<p>We encountered an error</p>
</Banner>
</div>
</Layout.Section>
</Layout>
</Page>
);
}
19 changes: 14 additions & 5 deletions components/providers/AppBridgeProvider.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMemo, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { Provider } from "@shopify/app-bridge-react";
import { Banner, Layout, Page } from "@shopify/polaris";
import { NavigationMenu, Provider } from "@shopify/app-bridge-react";
import { Outlet, useLocation, useNavigate } from "react-router-dom";
import { useMemo, useState } from "react";

/**
* A component to configure App Bridge.
Expand All @@ -12,7 +12,7 @@ import { Banner, Layout, Page } from "@shopify/polaris";
*
* See: https://shopify.dev/apps/tools/app-bridge/getting-started/using-react
*/
export function AppBridgeProvider({ children }) {
export function AppBridgeProvider() {
const location = useLocation();
const navigate = useNavigate();
const history = useMemo(
Expand Down Expand Up @@ -86,7 +86,16 @@ export function AppBridgeProvider({ children }) {

return (
<Provider config={appBridgeConfig} router={routerConfig}>
{children}
<Outlet />

<NavigationMenu
navigationLinks={[
{
label: "Page name",
destination: "/pagename",
},
]}
/>
</Provider>
);
}
43 changes: 24 additions & 19 deletions Routes.jsx → components/providers/AppRouterProvider.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Routes as ReactRouterRoutes, Route } from "react-router-dom";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import { AppBridgeProvider } from "../../components";
import ErrorBoundary from "../../components/ErrorBoundary";

/**
* File-based routing.
Expand All @@ -10,31 +12,31 @@ import { Routes as ReactRouterRoutes, Route } from "react-router-dom";
* * `/pages/blog/[id].jsx` matches `/blog/123`
* * `/pages/[...catchAll].jsx` matches any URL not explicitly matched
*
* @param {object} pages value of import.meta.globEager(). See https://vitejs.dev/guide/features.html#glob-import
*
* @return {Routes} `<Routes/>` from React Router, with a `<Route/>` for each file in `pages`
* @return {RouterProvider} `<RouterProvider/>` from React Router, with a `<Route/>` for each file in `pages`
*/
export default function Routes({ pages }) {

export function AppRouterProvider() {
// Any .tsx or .jsx files in /pages will become a route
// See https://vitejs.dev/guide/features.html#glob-import
const pages = import.meta.globEager('../../pages/**/!(*.test.[jt]sx)*.([jt]sx)');
const routes = useRoutes(pages);
const routeComponents = routes.map(({ path, component: Component }) => (
<Route key={path} path={path} element={<Component />} />
));
const NotFound = routes.find(({ path }) => path === '/notFound').element;

routes.push({path: '*', element: NotFound, errorElement: <ErrorBoundary />});

const NotFound = routes.find(({ path }) => path === "/notFound").component;
const router = createBrowserRouter([{
element: <AppBridgeProvider />,
children: routes
}]);

return (
<ReactRouterRoutes>
{routeComponents}
<Route path="*" element={<NotFound />} />
</ReactRouterRoutes>
);
return <RouterProvider router={router} />;
}

function useRoutes(pages) {
const routes = Object.keys(pages)
.map((key) => {
let path = key
.replace("./pages", "")
.replace("../../pages", "")
.replace(/\.(t|j)sx?$/, "")
/**
* Replace /index with /
Expand All @@ -58,12 +60,15 @@ function useRoutes(pages) {
console.warn(`${key} doesn't export a default React component`);
}

const Component = pages[key].default;

return {
path,
component: pages[key].default,
element: <Component />,
errorElement: <ErrorBoundary />
};
})
.filter((route) => route.component);
.filter((route) => route.element);

return routes;
}
}
1 change: 1 addition & 0 deletions components/providers/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { AppBridgeProvider } from "./AppBridgeProvider";
export { AppRouterProvider } from "./AppRouterProvider";
export { QueryProvider } from "./QueryProvider";
export { PolarisProvider } from "./PolarisProvider";
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-query": "^3.34.19",
"react-router-dom": "^6.3.0",
"react-router-dom": "^6.9.0",
"vite": "^2.8.6"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions pages/pagename.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Card, Page, Layout, TextContainer, Text } from "@shopify/polaris";
import { Card, Layout, Page, Text, TextContainer } from "@shopify/polaris";
import { TitleBar } from "@shopify/app-bridge-react";

export default function PageName() {
Expand Down Expand Up @@ -38,7 +38,7 @@ export default function PageName() {
</Layout.Section>
<Layout.Section secondary>
<Card sectioned>
<Heading>Heading</Heading>
<Text variant="headingMd" as="h2">Heading</Text>
<TextContainer>
<p>Body</p>
</TextContainer>
Expand Down