ClientRouter

By default, App Bridge applies URL changes from outside your app, such as changes from a navigation item being clicked, by updating the iframe URL. If your app uses client-side routing, such as React Router, then you need to override this behaviour to avoid unnecessary full-page reloads.

ClientRouter prevents App Bridge from changing the iframe URL, and lets you provide a client-side router, for example react-router, to handle navigation.

You can use ClientRouter as a hook (useClientRouting) or a component (<ClientRouter />).

ClientRouter can be used with any routing system that provides a history.replace method, which accepts a string for the updated path:

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

export interface History {
  replace(path: string): void;
}

export interface Props {
  history: History;
}

useClientRouting hook

Import the Provider and useClientRouting hook from App Bridge React. Only one Provider is needed for your application, and the hook must be called from inside the Provider.

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 MyRouter from '../MyRouter';

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

function MyRouter(props: RouterProps) {
  const {history} = props;

  useClientRouting(history);

  return null;
}

export default withRouter(ClientRouter);

<ClientRouter /> component

Import the Provider and <ClientRouter> components. Only one Provider is needed for your application, and the component must be a child of the Provider.

The following example assumes your app uses the withRouter enhancer from react-router.

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

import MyRouter from '../MyRouter';

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

function MyRouter(props: RouterProps) {
  const {history} = props;
  return <ClientRouter history={history} />;
};

export default withRouter(ClientRouter);