# Modal Component
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

```jsx
import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react';

export function MyModal() {
  const shopify = useAppBridge();

  return (
    <>
      <button onClick={() => shopify.modal.show('my-modal')}>Open Modal</button>
      <Modal id="my-modal">
        <p>Message</p>
        <TitleBar title="Title">
          <button variant="primary">Label</button>
          <button onClick={() => shopify.modal.hide('my-modal')}>Label</button>
        </TitleBar>
      </Modal>
    </>
  );
}

```


## 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.
### _UIModalAttributes

### children
The content to display within a Modal. You can provide a single HTML element with children and the [ui-title-bar](/docs/api/app-bridge-library/web-components/ui-title-bar) element to configure the Modal title bar.
### id
A unique identifier for the Modal
### src
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](/docs/api/app-bridge-library/web-components/ui-title-bar) and [ui-save-bar](/docs/api/app-bridge-library/web-components/ui-save-bar) elements will be ignored.
### variant
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.
### title
The title of the title bar. Can also be set via <code>document.title</code>.
## Related
- [Modal](/docs/api/app-bridge-library/apis/modal)
- [ui-modal](/docs/api/app-bridge-library/web-components/ui-modal)
- [useAppBridge](/docs/api/app-bridge-library/react-hooks/useappbridge)
- [TitleBar](/docs/api/app-bridge-library/react-components/titlebar-component)
- [SaveBar](/docs/api/app-bridge-library/react-components/savebar-component)
## Examples
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.
### Modals with different options

### Opening a max size Modal

```jsx
import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react';

export function MyModal() {
  const shopify = useAppBridge();

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; shopify.modal.show('my-modal')}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal" variant="max"&gt;
        &lt;div&gt;&lt;/div&gt;
        &lt;TitleBar&gt;
          &lt;button variant="primary"&gt;Primary action&lt;/button&gt;
          &lt;button&gt;Secondary action&lt;/button&gt;
        &lt;/TitleBar&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

```


### Specifying a Modal size

```jsx
import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react';

export function MyModal() {
  const shopify = useAppBridge();

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; shopify.modal.show('my-modal')}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal" variant="large"&gt;
        &lt;div&gt;&lt;/div&gt;
        &lt;TitleBar&gt;
          &lt;button variant="primary"&gt;Primary action&lt;/button&gt;
          &lt;button&gt;Secondary action&lt;/button&gt;
        &lt;/TitleBar&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

```


### Specifying a title for the Modal

```jsx
import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react';

export function MyModal() {
  const shopify = useAppBridge();

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; shopify.modal.show('my-modal')}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal"&gt;
        &lt;p&gt;Hello, World!&lt;/p&gt;
        &lt;TitleBar title="My Modal"&gt;&lt;/TitleBar&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

```


### Adding primary and secondary actions to a Modal

```jsx
import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react';

export function MyModal() {
  const shopify = useAppBridge();

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; shopify.modal.show('my-modal')}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal"&gt;
        &lt;p&gt;Hello, World!&lt;/p&gt;
        &lt;TitleBar&gt;
          &lt;button variant="primary" onClick={() =&gt; console.log('Saving')}&gt;
            Save
          &lt;/button&gt;
          &lt;button onClick={() =&gt; console.log('Cancelling')}&gt;Cancel&lt;/button&gt;
        &lt;/TitleBar&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

```


### Using a modal for a destructive action

```jsx
import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react';

export function MyModal() {
  const shopify = useAppBridge();

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; shopify.modal.show('my-modal')}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal"&gt;
        &lt;p&gt;If you delete this resource, it can't be undone.&lt;/p&gt;
        &lt;TitleBar title="Delete this resource"&gt;
          &lt;button
            variant="primary"
            tone="critical"
            onClick={() =&gt; console.log('Deleting')}
          &gt;
            Delete
          &lt;/button&gt;
          &lt;button onClick={() =&gt; console.log('Cancelling')}&gt;Cancel&lt;/button&gt;
        &lt;/TitleBar&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

```


### Modal events

### Subscribing to Show

```jsx
import {Modal, useAppBridge} from '@shopify/app-bridge-react';

export function MyModal() {
  const shopify = useAppBridge();

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; shopify.modal.show('my-modal')}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal" onShow={() =&gt; console.log('Modal is showing')}&gt;
        &lt;p&gt;Message&lt;/p&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

```


### Subscribing to Hide

```jsx
import {Modal, useAppBridge} from '@shopify/app-bridge-react';

export function MyModal() {
  const shopify = useAppBridge();

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; shopify.modal.show('my-modal')}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal" onHide={() =&gt; console.log('Modal is hiding')}&gt;
        &lt;button onclick="document.getElementById('my-modal').hide()"&gt;
          Hide Modal
        &lt;/button&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

```


### Modal controls

### Showing a Modal with the `open` prop

```jsx
import {useState} from 'react';
import {Modal, TitleBar} from '@shopify/app-bridge-react';

export function MyModal() {
  const [modalOpen, setModalOpen] = useState(false);

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; setModalOpen(true)}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal" open={modalOpen}&gt;
        &lt;p&gt;Message&lt;/p&gt;
        &lt;TitleBar title="My Modal"&gt;
          &lt;button onClick={() =&gt; setModalOpen(false)}&gt;Label&lt;/button&gt;
        &lt;/TitleBar&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

```


### Using a src URL to load content

### Loading content from a URL

```jsx
// main app
import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react';

export function MyModal() {
  const shopify = useAppBridge();

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; shopify.modal.show('my-modal')}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal" src="/my-route"&gt;
        &lt;TitleBar title="Title"&gt;
          &lt;button variant="primary"&gt;Label&lt;/button&gt;
          &lt;button onClick={() =&gt; shopify.modal.hide('my-modal')}&gt;Label&lt;/button&gt;
        &lt;/TitleBar&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

// my-route.html
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="shopify-api-key" content="%SHOPIFY_API_KEY%" /&gt;
    &lt;script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"&gt;&lt;/script&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;h1&gt;My separate route&lt;/h1&gt;
    &lt;script src="./my-route.jsx" type="module"&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;

// my-route.jsx
export function MyRoute() {
  return (
    &lt;h1&gt;My separate route&lt;/h1&gt;
  );
}



```


### Communicating between the Modal and the parent window

```jsx
// main app
import {Modal, TitleBar, useAppBridge} from '@shopify/app-bridge-react';
import {useEffect} from 'react';

export function MyModal() {
  const shopify = useAppBridge();

  useEffect(() =&gt; {
    function handleMessageFromModal(ev) {
      console.log('Message received in main app:', ev.data);
    }

    window.addEventListener('message', handleMessageFromModal)
    return () =&gt; {
      window.removeEventListener('message', handleMessageFromModal)
    }
  }, [])

  const openModal = async () =&gt; {
    await shopify.modal.show('my-modal');
    sendMessageToModal('Hello from the main app');
  }

  const sendMessageToModal = (message) =&gt; {
    document.getElementById('my-modal').contentWindow.postMessage(message, location.origin);
  }

  return (
    &lt;&gt;
      &lt;button onClick={openModal}&gt;Open Modal&lt;/button&gt;
      &lt;Modal id="my-modal" src="/my-route"&gt;
        &lt;TitleBar title="Title"&gt;
          &lt;button variant="primary"&gt;Label&lt;/button&gt;
          &lt;button onClick={() =&gt; shopify.modal.hide('my-modal')}&gt;Label&lt;/button&gt;
        &lt;/TitleBar&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

// my-route.html
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="shopify-api-key" content="%SHOPIFY_API_KEY%" /&gt;
    &lt;script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"&gt;&lt;/script&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;h1&gt;My separate route&lt;/h1&gt;
    &lt;script src="./my-route.jsx" type="module"&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;

// my-route.jsx
import {useEffect} from 'react';

export function MyRoute() {
  useEffect(() =&gt; {
    function handleMessageFromMainApp(ev) {
      console.log('Message received in modal:', ev.data);
    }

    window.addEventListener('message', handleMessageFromMainApp)
    return () =&gt; {
      window.removeEventListener('message', handleMessageFromMainApp)
    }
  }, [])

  const sendMessageToMainApp = (message) =&gt; {
    window.opener.postMessage(message, location.origin);
  }

  return (
    &lt;button onClick={() =&gt; sendMessageToMainApp('Hello from the modal')}&gt;
      Send message
    &lt;/button&gt;
  );
}


```


### Opening a base modal within a max src modal

```jsx
// main app
import {Modal, useAppBridge} from '@shopify/app-bridge-react';
export function MyModal() {
  const shopify = useAppBridge();
  return (
    &lt;&gt;
      &lt;Modal src="/my-route" variant="max" id="my-modal" /&gt;
      &lt;button onClick={() =&gt; shopify.modal.show("my-modal")}&gt;Open&lt;/button&gt;
      &lt;Modal id="my-nested-modal"&gt;
        &lt;p&gt;Message&lt;/p&gt;
      &lt;/Modal&gt;
    &lt;/&gt;
  );
}

// my-route.js
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="shopify-api-key" content="%SHOPIFY_API_KEY%" /&gt;
    &lt;script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;button onclick="window.opener.shopify.modal.show('my-nested-modal')"&gt;Open&lt;/button&gt;
  &lt;/body&gt;
&lt;/html&gt;
```