RoutePropagator

When a user navigates inside an embedded app, the URL of the embedded app iframe changes. If the user reloads the page, then the navigation isn't reflected in the URL of the parent page.

RoutePropagator lets you synchronize a Shopify embedded app's URL with the parent page.

You can use RoutePropagator as a hook (useRoutePropagation) or a component (<RoutePropagator />). The package can be used with any routing solution.

Both the hook and component versions of this library needs to be mounted inside the Provider component and take the same location parameter:

import {ClientApplication} from '@shopify/app-bridge';

export type LocationOrHref =
  | string
  | {search: string; hash: string; pathname: string};

export interface Props {
  location: LocationOrHref;
}

You can also use the App Bridge History API to keep the parent URL in sync manually.

useRoutePropagation

Import the Provider and useRoutePropagation hook. Only one Provider is needed for your application. The following example assumes your app uses the withRouter enhancer from react-router.

// App.tsx
import React from 'react';
import {BrowserRouter} from 'react-router';
import {Provider as AppBridgeProvider} from '@shopify/app-bridge-react';

import Routes from '../Routes';

export default function MyApp() {
  return (
    <BrowserRouter>
      <AppBridgeProvider
        config={{
          apiKey: 'API key from Shopify Partner Dashboard',
          shopOrigin: shopOrigin,
        }}
      >
        <Routes />
      </AppBridgeProvider>
    </BrowserRouter>
  );
})
// Routes.tsx
import React from 'react';
import {Switch, Route, RouteComponentProps, withRouter} from 'react-router'
import {useRoutePropagation} from '@shopify/app-bridge-react';

function Routes(props: RouteComponentProps) {
  const {location} = props;

  useRoutePropagation(location);

  return (
    <>
      <Switch>
        <Route exact path="/">
        { /* other routes */ }
      </Switch>
    </>
  );
}

export default withRouter(Routes);

<RoutePropagator />

Import the Provider and <RoutePropagator> components. Only one Provider is needed for your application. The following example assumes your app uses:

// App.tsx
import React from 'react';
import {BrowserRouter, Switch} from 'react-router';
import {Provider as AppBridgeProvider} from '@shopify/app-bridge-react';

import RoutePropagator from '../RoutePropagator';

export default function MyApp() {
  return (
    <BrowserRouter>
      <AppBridgeProvider
        config={{
          apiKey: 'API key from Shopify Partner Dashboard',
          shopOrigin: shopOrigin,
        }}
      >
        <RoutePropagator />
        <Switch>
          <Route exact path="/">
          { /* other routes */ }
        </Switch>
      </AppBridgeProvider>
    </BrowserRouter>
  );
})
// RoutePropagator.tsx
import React from 'react';
import {RouteComponentProps, withRouter} from 'react-router';
import {RoutePropagator as AppBridgeRoutePropagator} from '@shopify/app-bridge-react';

function RoutePropagator(props: RouteComponentProps) {
  const {location} = props;
  return <AppBridgeRoutePropagator location={location} />;
};

export default withRouter(RoutePropagator);