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.