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.
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 */ );
}
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:
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
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.