I followed Shopify’s guide, until the end of 4th step, to develop a Next JS app and I’ve setup two pages (embedded app navigation), Home and Page1.
Now, when I click to open both pages, the app is doing a reload instead of routing…
You can see here the flickering issue – https://youtu.be/45RvYgxC7C0
Any help on this would be very appreciated.
_app.js
import React from "react";
import App from "next/app";
import Head from "next/head";
import { AppProvider } from "@shopify/polaris";
import { Provider } from "@shopify/app-bridge-react";
import Cookies from "js-cookie";
import "@shopify/polaris/dist/styles.css";
import "../css/styles.css";
import lang from "@shopify/polaris/locales/en.json";
export default class MyApp extends App {
render() {
const { Component, pageProps } = this.props;
const config = { apiKey: API_KEY, shopOrigin: Cookies.get("shopOrigin"), forceRedirect: true };
return (
<React.Fragment>
<Head>
<title>My App</title>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="favicon.ico" />
</Head>
<Provider config={config}>
<AppProvider i18n={lang}>
<Component {...pageProps} />
</AppProvider>
</Provider>
</React.Fragment>
);
}
}
home.js
import React from "react";
import { Page, Layout, Card, FooterHelp, Link } from "@shopify/polaris";
export default function Home() {
return (
<Page title="Home">
<Layout>
<Layout.Section>
<Card title="Online store dashboard" sectioned>
<p>View a summary of your online store’s performance.</p>
</Card>
</Layout.Section>
<Layout.Section>
<FooterHelp>
Learn more about{" "}
<Link url="#" external>
our app
</Link>
</FooterHelp>
</Layout.Section>
</Layout>
</Page>
);
}
Page1.js
import React from "react";
import { Page, Layout, Card, FooterHelp, Link } from "@shopify/polaris";
export default function Page1() {
return (
<Page title="Page1">
<Layout>
<Layout.Section>
<Card title="Online store dashboard" sectioned>
<p>View a summary of your online store’s performance.</p>
</Card>
</Layout.Section>
<Layout.Section>
<FooterHelp>
Learn more about{" "}
<Link url="#" external>
our app
</Link>
</FooterHelp>
</Layout.Section>
</Layout>
</Page>
);
}
2
Answers
Everything works correctly, you are loading the whole page every time you request a new
nextjs
page. In order to have parts of your layout persistent between page loads, you need to move them to the_app.js
.Take a look at the official dynamic app layout example.
If you want to load a sub-section of the page without reloading the whole page you can use a
query
in combination with shallow routing e.gexample.com/settings
andexample.com/settings?section='profile'
When using Shopify’s app-bridge, it has a default behavior of navigating to a new route within the iframe that holds your app (and thus completely reloading the app), whereas React implements a client-side router.
Shopify doesn’t provide a 100% plug-and-play solution for using client-side routing, but they do make it pretty easy with their ClientRouter component.
The examples on that page are for react-router, not Next.js’s router, but the same idea applies to next/router.
For example, a simple router component could look like:
After creating that component, drop it in the _app.js file inside the Shopify routers, for example:
When _app loads, it will now subscribe to changes from appBridge and let appBridge know to send a signal to the client rather than reload the entire iframe. If you apply any routing within the app, such as one page to another, it will also now update the browser’s address bar.