--- title: Migrate your app to Shopify App Bridge React 4.x.x description: Learn how to migrate your app to the latest version of Shopify App Bridge React. api_name: app-bridge source_url: html: https://shopify.dev/docs/api/app-bridge/migration-guide-react md: https://shopify.dev/docs/api/app-bridge/migration-guide-react.md --- ExpandOn this page * [Requirements](https://shopify.dev/docs/api/app-bridge/migration-guide-react#requirements) * [Benefits of migration](https://shopify.dev/docs/api/app-bridge/migration-guide-react#benefits-of-migration) * [Step 1: Add the app-bridge.​js script tag](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-1-add-the-app-bridgejs-script-tag) * [Step 2: Upgrade your @shopify/app-bridge-react dependency](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-2-upgrade-your-shopify-app-bridge-react-dependency) * [Step 3: Remove the Provider setup](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-3-remove-the-provider-setup) * [Step 4: Update components](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-4-update-components) * [Step 5: Update hooks](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-5-update-hooks) # Migrate your app to Shopify App Bridge React 4.x.x If you have an app that uses components and hooks from Shopify App Bridge React 3.x.x, then you can follow this guide to upgrade your components and hooks to the latest version. *** ## Requirements * [`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) version 18 or higher * A Node.js package manager: either [npm](https://www.npmjs.com/get-npm), [Yarn 1.x](https://classic.yarnpkg.com/lang/en/docs/install), or [pnpm](https://pnpm.io/installation) *** ## Benefits of migration When you migrate your app to use Shopify App Bridge React 4.x.x, you can take advantage of the following improvements to the developer experience: ### Simplified configuration Shopify App Bridge React 4.x.x simplifies the configuration process. Apps no longer need to use a React Provider or the `host` config. Instead, they only need to provide their API key to the `app-bridge.js` script. ### Automatic updates The `app-bridge.js` script automatically keeps itself up to date, so you can access new Shopify App Bridge APIs as soon as they're released. ### Use web standards The latest version of Shopify App Bridge embraces the web platform and web standards, so you can use web APIs you're already familiar with. For more information about the motivation behind App Bridge, refer to [Shopify's platform is the Web platform](https://shopify.engineering/shopifys-platform-is-the-web-platform). ### Direct API access Take advantage of the new Direct API access feature. You can make requests to the Admin API directly from your app using the standard [web fetch API](https://developer.mozilla.org/en-US/docs/Web/API/fetch). For more information about Direct API access, refer to the [documentation](https://shopify.dev/docs/api/app-home#direct-api-access). ### Modals with custom content Add modals to your app with custom content using the Modal component from Shopify App Bridge React. This enables you to create rich modal experiences that render directly in the Shopify admin. These modals are fast too, because they're preloaded. *** ## Step 1: Add the `app-bridge.js` script tag Include the `app-bridge.js` script tag in your app. Replace `%SHOPIFY_API_KEY%` with your app's [client ID](https://shopify.dev/docs/apps/build/authentication-authorization/client-secrets#retrieve-your-apps-client-credentials). This configures your app to use Shopify App Bridge. The `app-bridge.js` script is CDN-hosted, so your app always gets the latest version of it. ## index.html ```html ``` *** ## Step 2: Upgrade your `@shopify/app-bridge-react` dependency Install or upgrade the `@shopify/app-bridge-react` dependency with your package manager. ## Terminal ```terminal npm install @shopify/app-bridge-react@latest ``` ```terminal yarn add @shopify/app-bridge-react@latest ``` ```terminal pnpm add @shopify/app-bridge-react@latest ``` *** ## Step 3: Remove the `Provider` setup In previous versions of App Bridge React, you needed to set up a [context provider](https://shopify.dev/docs/api/app-bridge/previous-versions/app-bridge-from-npm/using-react#provider) to enable component and hook usage. This is no longer needed, as all the setup for Shopify App Bridge is done through the `app-bridge.js` script tag that you added in [step 1](https://shopify.dev/docs/api/app-bridge/migration-guide#step-1-add-the-app-bridge-js-script-tag). Remove all `Provider` import statements and usages from `@shopify/app-bridge-react` in your app: ## Provider setup ## 3.x.x ```jsx import ReactDOM from 'react-dom'; import {Provider} from '@shopify/app-bridge-react'; function MyApp() { return (
My app
); } const root = document.createElement('div'); document.body.appendChild(root); ReactDOM.createRoot(root).render(); ``` ## 4.x.x ```jsx import ReactDOM from 'react-dom'; function MyApp() { return (
My app
); } const root = document.createElement('div'); document.body.appendChild(root); ReactDOM.createRoot(root).render(); ``` *** ## Step 4: Update components The following components and props have been refactored, renamed, or removed. Review and update the following components as described: * [Modal](#modal) * Updated props: * [`size`](#size-prop-renamed-to-variant) * [`message`](#message-prop-removed) * [`title`](#title-prop-removed) * [`onClose`](#onclose-prop-renamed-onhide) * [`primaryAction` and `secondaryActions` props](#primaryaction-and-secondaryactions-props-removed) * [`setupModalAutoSizing` utility](#setupmodalautosizing-utility) * [Communication with the parent page](#communication-with-the-parent-page) * [TitleBar](#titlebar) * Updated props: * [`primaryAction`, `secondaryActions`, and `actionGroups`](#primaryaction-secondaryactions-and-actiongroups-props-removed) * [`breadcrumbs`](#breadcrumbs-prop-removed) * [NavigationMenu](#navigationmenu-renamed-navmenu) ### `Modal` The [`Modal`](https://shopify.dev/docs/api/app-home/react-components/modal) component enables you to display an overlay that prevents interaction with the rest of the app until dismissed. The following updates have been made to the `Modal` component's behaviour and props. #### `size` prop renamed to `variant` The `size` prop has been renamed [`variant`](https://shopify.dev/docs/api/app-home/react-components/modal#modalcomponent-propertydetail-variant) to more accurately describe it's purpose. The `variant` prop accepts plain strings rather than constants: ## size > variant ## 3.x.x ```jsx ``` ## 4.x.x ```jsx ``` Note The `Modal` component has a new variant called `max`. Refer to the [`max` modal example](https://shopify.dev/docs/api/app-home/react-components/modal#modals-with-different-options-opening-a-max-size-modal) for more details. #### `message` prop removed The `Modal` component no longer accepts a `message` prop. To migrate your code, replace any instances where you used the `message` prop with React elements as children of the Modal component. ## message prop removed ## 3.x.x ```jsx ``` ## 4.x.x ```jsx

Hello world!

``` #### `title` prop removed The `Modal` component no longer accepts a `title` prop, Instead, now uses the [`TitleBar`](https://shopify.dev/docs/api/app-home/react-components/titlebar) component to control the modal title. ## title prop removed ## 3.x.x ```jsx ``` ## 4.x.x ```jsx ``` #### `onClose` prop renamed `onHide` The `onClose` prop has been renamed to `onHide` in the new `Modal` component to standardize the props with the [admin extensions components](https://shopify.dev/docs/api/admin-extensions/2024-01/components) library. ## onClose > onHide ## 3.x.x ```jsx ``` ## 4.x.x ```jsx ``` #### `primaryAction` and `secondaryActions` props removed The `Modal` component no longer accepts the `primaryAction` and `secondaryActions` props. It now uses the [`TitleBar`](https://shopify.dev/docs/api/app-home/react-components/titlebar) component to control the modal action buttons. A `TitleBar` component in a `Modal` component accepts only one secondary action. ## primaryAction and secondaryActions props removed ## 3.x.x ```jsx ``` ## 4.x.x ```jsx ``` #### `setupModalAutoSizing` utility In previous versions, you needed to set up [modal auto-sizing](https://shopify.dev/docs/api/app-bridge/previous-versions/actions/modal#set-modal-size-automatically) to allow your modal to update its height to fit the page content. This is no longer needed, because auto-sizing is set automatically. #### Communication with the parent page In previous versions, you needed to use the [`Modal.Action.DATA` action](https://shopify.dev/docs/api/app-bridge/previous-versions/actions/modal#communicate-with-the-parent-page) to communicate between the parent page and the modal. There are now two ways to communicate between the modal and the parent page. If you're using a modal with custom content, you can use the [Broadcast Channel Web API](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API) to communicate with the parent page. ## Communication with the parent page ## 3.x.x ```jsx function MyModal() { return ( ) } // component rendered at /modal-route function ModalRouteComponent() { const app = useAppBridge(); const sendMessageToApp = () => { app.dispatch(Modal.data({message: 'Hi, this is the modal!'})); } return (
) } function MyApp() { const app = useAppBridge(); useEffect(() => { app.subscribe(Modal.Action.DATA, (data) => { console.log('Received message from modal: ', data.message); }); }, []); return (
My app
) } ``` ## 4.x.x ```jsx const modalChannel = new BroadcastChannel('my-modal'); function MyModal() { const sendMessageToApp = () => { modalChannel.postMessage('Hi, this is the modal!'); } return ( ) } function MyApp() { useEffect(() => { modalChannel.addEventListener('message', (event) => { console.log('Received message from modal: ', event); }); }, []); return (
My app
) } ``` If you're using a modal with a `src` prop, you can use the [postMessage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) to communicate with the parent page. You can access `postMessage` through the `window.opener` object in the modal and through the `modal.contentWindow` object in the parent page. ## Communication with the parent page ## 3.x.x ```jsx function MyModal() { return ( ) } // component rendered at /modal-route function ModalRouteComponent() { const app = useAppBridge(); const sendMessageToApp = () => { app.dispatch(Modal.data({message: 'Hi, this is the modal!'})); } return (
) } function MyApp() { const app = useAppBridge(); useEffect(() => { app.subscribe(Modal.Action.DATA, (data) => { console.log('Received message from modal: ', data.message); }); }, []); return (
My app
) } ``` ## 4.x.x ```jsx function MyModal() { return ( ) } // component rendered at /modal-route function ModalRouteComponent() { const app = useAppBridge(); useEffect(() => { function handleMessageFromMainApp(ev) { console.log('Message received in modal:', ev.data); } window.addEventListener('message', handleMessageFromMainApp) return () => { window.removeEventListener('message', handleMessageFromMainApp) } }, []) const sendMessageToApp = () => { window.opener.postMessage('Hi, this is the modal!', location.origin); } return (
) } function MyApp() { const app = useAppBridge(); useEffect(() => { function handleMessageFromModal(ev) { console.log('Message received in main app:', ev.data); } window.addEventListener('message', handleMessageFromModal) return () => { window.removeEventListener('message', handleMessageFromModal) } }, []) const sendMessageToApp = () => { const modal = document.getElementById('my-modal'); modal.contentWindow.postMessage('Hi, this is the main app!', location.origin); } return (
My app
) } ``` ### `TitleBar` The [`TitleBar`](https://shopify.dev/docs/api/app-home/react-components/titlebar) component allows you to populate a standardized title bar with button actions and navigation breadcrumbs. It can now also be used inside a `Modal` component to control the title and footer content to reduce the number of APIs that you need to learn. The following updates have been made to the title bar component's behaviour and props. #### `primaryAction`, `secondaryActions`, and `actionGroups` props removed The `TitleBar` component no longer accepts the `primaryAction`, `secondaryActions`, and `actionGroups` props. Instead, to provide title bar actions, add `button` elements as children. ## primaryAction ## 3.x.x ```jsx ``` ## 4.x.x ```jsx
``` #### `breadcrumbs` prop removed The `TitleBar` component no longer accepts the `breadcrumbs` prop. Instead, a breadcrumb can be added to the title bar using a child `a` or `button` element with the `variant="breadcrumb"` attribute set. ## breadcrumbs prop removed ## 3.x.x ```jsx ``` ## 4.x.x ```jsx Breadcrumb ``` ### Navigation​Menu The navigation menu for your app is now created using the `` Polaris web component instead of a React component. When using React, you can render this component directly in your JSX. #### Migration from Navigation​Menu React component The previous React `NavigationMenu` component with `navigationLinks` and `matcher` props has been replaced with the `` web component that accepts link elements as children. The active link is automatically matched based on the current URL. ## NavigationMenu migration ## 3.x.x ```jsx link.destination === location.pathname} /> ``` ## 4.x.x ```jsx Home Templates Settings ``` ### Other removed components All other React components from previous versions have been removed, and replaced by new APIs provided through the [`shopify` global variable](https://shopify.dev/docs/api/app-home#shopify-global-variable). Refer to the following table to learn about the API replacement for each component: | Component | New API | | - | - | | `ContextualSaveBar` | [Contextual Save Bar API](https://shopify.dev/docs/api/app-home/apis/contextual-save-bar) | | `Loading` | [Loading API](https://shopify.dev/docs/api/app-home/apis/loading) | | `unstable_Picker` | [Picker API](https://shopify.dev/docs/api/app-home/apis/picker) | | `ResourcePicker` | [ResourcePicker API](https://shopify.dev/docs/api/app-home/apis/resource-picker) | | `Toast` | [Toast API](https://shopify.dev/docs/api/app-home/apis/toast) | *** ## Step 5: Update hooks The following hooks have been refactored, renamed, or removed. Review and update the following components as described: ### `useAppBridge` hook The [`useAppBridge`](https://shopify.dev/docs/api/app-home/react-hooks/useappbridge) hook included in the most recent version of Shopify App Bridge functions differently than the previous `useAppBridge` hook. Instead of returning the App Bridge `app` instance, it returns the `shopify` global variable, which is used to access App Bridge APIs such as `toast` and `resourcePicker`. As the `shopify` variable is only available in a browser context, the `useAppBridge` hook throws helpful error messages when used in a server context or in a misconfigured app. You no longer need to use the `app` reference returned from old uses of the `useAppBridge` hook as App Bridge handles configuration for you. The following is an example: ## 4.x.x ```jsx function GenerateBlogPostButton() { const shopify = useAppBridge(); function generateBlogPost() { // Handle generating shopify.toast.show('Blog post template generated'); } return ; } ``` ### Other removed hooks All other React hooks from previous versions have been removed, and replaced by new APIs provided through the [`shopify` global variable](https://shopify.dev/docs/api/app-home#shopify-global-variable). In most cases, you can use the `useAppBridge` hook in place of these hooks, and access the corresponding API through the returned `shopify` global variable. Refer to the following table to learn about the API replacement for each hook: | Hook | Replacement | | - | - | | `useAppBridgeState` | This functionality has been spread out across a few APIs. For example, to retrieve the current `staffMember`, use the [User API](https://shopify.dev/docs/api/app-home/apis/user). | | `useAuthenticatedFetch` | This hook is no longer needed, because App Bridge injects automatic authorization into the global `fetch` function. For more information, refer to [Resource Fetching](https://shopify.dev/docs/api/app-home/apis/resource-fetching). | | `useContextualSaveBar` | The contextual save bar is now automatically configured when you provide the `data-save-bar` attribute to a [form element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form). For more information, refer to [Contextual Save Bar](https://shopify.dev/docs/api/app-home/apis/contextual-save-bar). | | `useNavigate` | [Navigation API](https://shopify.dev/docs/api/app-home/apis/navigation) | | `useNavigationHistory` | [Navigation API](https://shopify.dev/docs/api/app-home/apis/navigation) | | `useToast` | [Toast API](https://shopify.dev/docs/api/app-home/apis/toast) | *** * [Requirements](https://shopify.dev/docs/api/app-bridge/migration-guide-react#requirements) * [Benefits of migration](https://shopify.dev/docs/api/app-bridge/migration-guide-react#benefits-of-migration) * [Step 1: Add the app-bridge.​js script tag](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-1-add-the-app-bridgejs-script-tag) * [Step 2: Upgrade your @shopify/app-bridge-react dependency](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-2-upgrade-your-shopify-app-bridge-react-dependency) * [Step 3: Remove the Provider setup](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-3-remove-the-provider-setup) * [Step 4: Update components](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-4-update-components) * [Step 5: Update hooks](https://shopify.dev/docs/api/app-bridge/migration-guide-react#step-5-update-hooks)