--- title: Modal Component description: >- The Modal API allows you to display an overlay that prevents interaction with the rest of the app until dismissed. It is used by customizing your Modal content with the `Modal` component and then opening it with the `shopify.modal.show('modal-id')` API. api_name: app-bridge-library source_url: html: >- https://shopify.dev/docs/api/app-bridge-library/react-components/modal-component md: >- https://shopify.dev/docs/api/app-bridge-library/react-components/modal-component.md --- # Modal Component Requires [`@shopify/app-bridge-react@v4`](https://www.npmjs.com/package/@shopify/app-bridge-react) and the [`app-bridge.js` script tag](https://shopify.dev/docs/api/app-bridge-library#getting-started) The Modal API allows you to display an overlay that prevents interaction with the rest of the app until dismissed. It is used by customizing your Modal content with the `Modal` component and then opening it with the `shopify.modal.show('modal-id')` API. ## Modal component The `Modal` component is available for use in your app. It configures a Modal to display in the Shopify Admin. The content you provide can be simple React elements or a `src` prop with a URL that will be loaded. * children HTMLCollection & UITitleBarAttributes The content to display within a Modal. You can provide a single HTML element with children and the [ui-title-bar](https://shopify.dev/docs/api/app-bridge-library/web-components/ui-title-bar) element to configure the Modal title bar. * id string A unique identifier for the Modal * src string The URL of the content to display within a Modal. If provided, the Modal will display the content from the provided URL and any children other than the [ui-title-bar](https://shopify.dev/docs/api/app-bridge-library/web-components/ui-title-bar) and [ui-save-bar](https://shopify.dev/docs/api/app-bridge-library/web-components/ui-save-bar) elements will be ignored. * variant 'small' | 'base' | 'large' | 'max' Default: "base" The size of the modal. Before the Modal is shown, this can be changed to any of the provided values. After the Modal is shown, this can can only be changed between `small`, `base`, and `large`. ### UITitleBarAttributes * children The children of the title bar. ```ts any ``` * title The title of the title bar. Can also be set via \document.title\. ```ts string ``` ```ts export interface UITitleBarAttributes extends _UITitleBarAttributes { children?: any; } ``` ### Examples * #### Modal ##### Default ```jsx import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <>

Message

); } ``` ## Preview ![](https://shopify.dev/images/templated-apis-screenshots/app-bridge-library/modal.png) ## Examples Modal options, variations, and events ### Modals with different options Opening a max size Modal Modal with max size Specifying a Modal size Modal with variant Specifying a title for the Modal Modal with title Adding primary and secondary actions to a Modal Modal with primary and secondary actions Using a modal for a destructive action Adding a critical button to a Modal ### Examples * #### Opening a max size Modal ##### Description Modal with max size ##### Default ```jsx import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <>
); } ``` * #### Specifying a Modal size ##### Description Modal with variant ##### Default ```jsx import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <>
); } ``` * #### Specifying a title for the Modal ##### Description Modal with title ##### Default ```jsx import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <>

Hello, World!

); } ``` * #### Adding primary and secondary actions to a Modal ##### Description Modal with primary and secondary actions ##### Default ```jsx import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <>

Hello, World!

); } ``` * #### Using a modal for a destructive action ##### Description Adding a critical button to a Modal ##### Default ```jsx import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <>

If you delete this resource, it can't be undone.

); } ``` ## Preview ![](https://shopify.dev/images/templated-apis-screenshots/app-bridge-library/modal-max.png) ### Modal events Subscribing to Show Using the `onShow` callback which is called when the Modal is opened Subscribing to Hide Using the `onHide` callback which is called when the Modal is closed ### Examples * #### Subscribing to Show ##### Description Using the \`onShow\` callback which is called when the Modal is opened ##### Default ```jsx import {Modal, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <> console.log('Modal is showing')}>

Message

); } ``` * #### Subscribing to Hide ##### Description Using the \`onHide\` callback which is called when the Modal is closed ##### Default ```jsx import {Modal, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <> console.log('Modal is hiding')}> ); } ``` ### Modal controls Showing a Modal with the \`open\` prop Modal controlled by the `open` prop ### Examples * #### Showing a Modal with the \`open\` prop ##### Description Modal controlled by the \`open\` prop ##### Default ```jsx import {useState} from 'react'; import {Modal, TitleBar} from '@shopify/app-bridge-react'; export function MyModal() { const [modalOpen, setModalOpen] = useState(false); return ( <>

Message

); } ``` ### Using a src URL to load content Loading content from a URL Loading content from a URL Communicating between the Modal and the parent window Communicating between the Modal and the parent window Opening a base modal within a max src modal This pattern is useful for displaying a dialog or prompt from within a max variant modal. ### Examples * #### Loading content from a URL ##### Description Loading content from a URL ##### Default ```jsx // main app import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <> ); } // my-route.html

My separate route

// my-route.jsx export function MyRoute() { return (

My separate route

); } ``` * #### Communicating between the Modal and the parent window ##### Description Communicating between the Modal and the parent window ##### Default ```jsx // main app import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react'; import {useEffect} from 'react'; export function MyModal() { const shopify = useAppBridge(); useEffect(() => { function handleMessageFromModal(ev) { console.log('Message received in main app:', ev.data); } window.addEventListener('message', handleMessageFromModal) return () => { window.removeEventListener('message', handleMessageFromModal) } }, []) const openModal = async () => { await shopify.modal.show('my-modal'); sendMessageToModal('Hello from the main app'); } const sendMessageToModal = (message) => { document.getElementById('my-modal').contentWindow.postMessage(message, location.origin); } return ( <> ); } // my-route.html

My separate route

// my-route.jsx import {useEffect} from 'react'; export function MyRoute() { useEffect(() => { function handleMessageFromMainApp(ev) { console.log('Message received in modal:', ev.data); } window.addEventListener('message', handleMessageFromMainApp) return () => { window.removeEventListener('message', handleMessageFromMainApp) } }, []) const sendMessageToMainApp = (message) => { window.opener.postMessage(message, location.origin); } return ( ); } ``` * #### Opening a base modal within a max src modal ##### Description This pattern is useful for displaying a dialog or prompt from within a max variant modal. ##### Default ```jsx // main app import {Modal, useAppBridge} from '@shopify/app-bridge-react'; export function MyModal() { const shopify = useAppBridge(); return ( <>

Message

); } // my-route.js ``` ## Related [![](https://shopify.dev/images/icons/32/pickaxe-1.png)![](https://shopify.dev/images/icons/32/pickaxe-1-dark.png)](https://shopify.dev/docs/api/app-bridge-library/apis/modal) [APIsModal](https://shopify.dev/docs/api/app-bridge-library/apis/modal) [![](https://shopify.dev/images/icons/32/pickaxe-1.png)![](https://shopify.dev/images/icons/32/pickaxe-1-dark.png)](https://shopify.dev/docs/api/app-bridge-library/web-components/ui-modal) [Web Componentsui-modal](https://shopify.dev/docs/api/app-bridge-library/web-components/ui-modal) [![](https://shopify.dev/images/icons/32/pickaxe-1.png)![](https://shopify.dev/images/icons/32/pickaxe-1-dark.png)](https://shopify.dev/docs/api/app-bridge-library/react-hooks/useappbridge) [HookuseAppBridge](https://shopify.dev/docs/api/app-bridge-library/react-hooks/useappbridge) [![](https://shopify.dev/images/icons/32/pickaxe-1.png)![](https://shopify.dev/images/icons/32/pickaxe-1-dark.png)](https://shopify.dev/docs/api/app-bridge-library/react-components/titlebar-component) [React ComponentsTitleBar](https://shopify.dev/docs/api/app-bridge-library/react-components/titlebar-component) [![](https://shopify.dev/images/icons/32/pickaxe-1.png)![](https://shopify.dev/images/icons/32/pickaxe-1-dark.png)](https://shopify.dev/docs/api/app-bridge-library/react-components/savebar-component) [React ComponentsSaveBar](https://shopify.dev/docs/api/app-bridge-library/react-components/savebar-component)