Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pages are reloaded instead of routed in shopify next js app

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>
    );
}
like image 700
Alexis Avatar asked Aug 18 '20 07:08

Alexis


People also ask

Why is my Shopify App so slow?

App generated with shopify CLI is extremely slow (due to ngrok and NextJS custom server, server side changes using the shopify official app take ages to reflect). Development experience is awful.

What is Shopify CLI and how to use it?

Shopify CLI is generating an app that does not work out of the box. App generated with shopify CLI is using old version of shopify node API and old version of all kind of dependencies (it still uses the koa-shopify-node-api dependency which is full of bug and being abandoned. Honest advice: stay away from this lib)

How do I deploy my next JS app?

You can check out the Next.js GitHub repository – your feedback and contributions are welcome! The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js. Check out our Next.js deployment documentation for more details.


Video Answer


1 Answers

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:

import {useEffect, useContext} from 'react';
import Router, { useRouter } from "next/router";
import { Context as AppBridgeContext } from "@shopify/app-bridge-react";
import { Redirect } from "@shopify/app-bridge/actions";
import { RoutePropagator as ShopifyRoutePropagator } from "@shopify/app-bridge-react";

const RoutePropagator = () => {
  const router = useRouter(); 
  const { route } = router;
  const appBridge = React.useContext(AppBridgeContext);

  // Subscribe to appBridge changes - captures appBridge urls 
  // and sends them to Next.js router. Use useEffect hook to 
  // load once when component mounted
  useEffect(() => {
    appBridge.subscribe(Redirect.Action.APP, ({ path }) => {
      Router.push(path);
    });
  }, []);

  return appBridge && route ? (
    <ShopifyRoutePropagator location={route} app={appBridge} />
  ) : null;
}

export default RoutePropagator;

After creating that component, drop it in the _app.js file inside the Shopify routers, for example:

<Provider config={config}>
  <AppProvider i18n={translations}>
    <RoutePropagator />
    <ApolloProvider client={client}>
      // child components
    </ApolloProvider>
  </AppProvider>
</Provider>

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.

like image 131
Drew Watkins Avatar answered Nov 15 '22 04:11

Drew Watkins