Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

NextJS with Dynamic Routing throwing AppBridge Error

Solved

NextJS with Dynamic Routing throwing AppBridge Error

12345vb
Shopify Partner
11 0 2

I am using NextJS to do dynamic routing

My file is called 

 

[itemId].js

 

Although to do dynamic routing, you need to specify getStaticPaths and  getStaticProps.
The minute I specify those, AppBridge throws an error. 

 

AppBridgeError: APP::ERROR::INVALID_CONFIG: host must be provided

 

 

I have tried to specifically adding host in both getStaticPaths and getStaticProps but it still asks to provide it. 
Below I have provided how those functions work, I just have a random value for host to not share it.

 

 

export const getStaticPaths = async (ctx) => {
    return {
        paths: [{ params: { itemId: "1", host: 'myhost' }}], 
       fallback: 'blocking',
    }
}

export async function getStaticProps(data) {
    return { 
        props: {itemId: "1", host: 'myhost'
    }
  }
}

 


Any help on getting dynamic routing working would be appreciated with some code examples if there are.

Thank you. 

Accepted Solution (1)
Paul_vd_Dool
Shopify Partner
112 6 99

This is an accepted solution.

Yup. I had that as well. I fixed that in my RoutePropagator. Can't remember what part exactly solved it, but here's what I have.

In _app.tsx I have:

<PolarisProvider>
      <AppBridgeProvider config={config}>
          <RoutePropagator />
          <ApolloProvider state={storedParams?.state}>
             <Component {...pageProps} />
          </ApolloProvider>
      </AppBridgeProvider>
    </PolarisProvider>

 

And then this is my full RoutePropagator:

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

function RoutePropagator() {
  const router = useRouter();
  const { route, asPath }: { route: string, asPath: string } = router;
  const appBridge: any = useContext( AppBridgeContext );

  useEffect( () => {
    appBridge.subscribe( Redirect.Action.APP, ( payload: any ) => {
      Router.push( payload.path );
    } );
  }, [appBridge] );

  return appBridge && route ? (
    //@ts-ignore
    <ShopifyRoutePropagator location={asPath} app={appBridge} />
  ) : null;
}

export default RoutePropagator;

 I believe it was the `useEffect()` that fixed it where I push the payload.path into the router when listening (.subscribe()) to app navigation events in appbridge.

Doppelganger - Managing duplicate user accounts

View solution in original post

Replies 8 (8)

Paul_vd_Dool
Shopify Partner
112 6 99

I believe your error is unrelated to your `getStaticPaths` functions. It would also happen if you'd have any other routing.

 

It is going wrong wherever you have this line of code:

<AppBridgeProvider config={config}>

Where `config` is:

const config = {
apiKey: process.env.NEXT_PUBLIC_SHOPIFY_API_PUBLIC_KEY,
forceRedirect: true,
shopOrigin,
host
};

The host is undefined. I've seen more people mention this, but `host` is not always returned by Shopify in the URL.

I've had to get a bit creative to solve this.

First I create an object of all the params from the url. If `host` is a part of that, I use that.
If that is not the case I check if `shop` is part of the params, because `host` is actually the `shop` but base64 encoded. I stumbled upon that little bit of information by pure luck. I did `btoa( shop )` and it worked and hasn't failed me yet so it must be true.

If `shop` also isn't part of the params, I just pluck it out of the start of the URL. I can't remember at the moment if it should be the full "shop-slug.myshopify.com" part or just what becomes before the ".myshopify.com" part: "shop-slug", but you can get there by trial and error.

 

So it would look something like this:

// get params from url
const params = getSearchParams( window.location.search );
let host;
if ( params?.host ) {
host = params.host;
} else if ( params?.shop ) {
host = btoa( params.shop );
} else {
host = btoa( /* get from url manually */ );
}

I hope this helps.

Doppelganger - Managing duplicate user accounts
12345vb
Shopify Partner
11 0 2

Thanks for your help. I feel like I am getting closer.

One other issue that came up, now since the host displays, the url changes though

if I visit /items/item/1 for example, everything loads up, but then the URL changes to:
/items/item/[itemId]   ... any idea on this? 

Paul_vd_Dool
Shopify Partner
112 6 99

This is an accepted solution.

Yup. I had that as well. I fixed that in my RoutePropagator. Can't remember what part exactly solved it, but here's what I have.

In _app.tsx I have:

<PolarisProvider>
      <AppBridgeProvider config={config}>
          <RoutePropagator />
          <ApolloProvider state={storedParams?.state}>
             <Component {...pageProps} />
          </ApolloProvider>
      </AppBridgeProvider>
    </PolarisProvider>

 

And then this is my full RoutePropagator:

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

function RoutePropagator() {
  const router = useRouter();
  const { route, asPath }: { route: string, asPath: string } = router;
  const appBridge: any = useContext( AppBridgeContext );

  useEffect( () => {
    appBridge.subscribe( Redirect.Action.APP, ( payload: any ) => {
      Router.push( payload.path );
    } );
  }, [appBridge] );

  return appBridge && route ? (
    //@ts-ignore
    <ShopifyRoutePropagator location={asPath} app={appBridge} />
  ) : null;
}

export default RoutePropagator;

 I believe it was the `useEffect()` that fixed it where I push the payload.path into the router when listening (.subscribe()) to app navigation events in appbridge.

Doppelganger - Managing duplicate user accounts
12345vb
Shopify Partner
11 0 2

Thank you! I am getting

TypeError : Cannot read properties of null (reading 'subscribe') from the useEffect() hook, I will do some investigations and let you know

Paul_vd_Dool
Shopify Partner
112 6 99

appBridge is undefined then. Do you have the dependency installed correctly?

These are the AppBridge related ones that I have:

"@shopify/app-bridge": "^2.0.4",
"@shopify/app-bridge-react": "^2.0.4",
"@shopify/app-bridge-utils": "^2.0.4",

If you have, running another `npm install` often works for me with stuff like this.

Doppelganger - Managing duplicate user accounts
12345vb
Shopify Partner
11 0 2

I was missing 

@Shopify/app-bridge


Installed it, removed node_modules and ran npm i again.

I also had the 

<RoutePropagator /> in the wrong spot. Had to be inside the <Provider> component in _app.js



Everything seems to be working! URL paths don't change change now to [itemId]. Thanks so much 🙂

Paul_vd_Dool
Shopify Partner
112 6 99

Great to hear. Happy to help.

 

Doppelganger - Managing duplicate user accounts
test6A
Shopify Partner
23 0 13

You saved my day! So grateful.