# ui-modal
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 `ui-modal` element and then opening it with the `show()` instance method or the `shopify.modal.show('modal-id')` API.
### Modal

```html
<ui-modal id="my-modal">
  <p>Message</p>
  <ui-title-bar title="Title">
    <button variant="primary">Label</button>
    <button onclick="document.getElementById('my-modal').hide()">Label</button>
  </ui-title-bar>
</ui-modal>

<button onclick="document.getElementById('my-modal').show()">Open Modal</button>

```


## ui-modal element
The `ui-modal` element is available for use in your app. It configures a Modal to display in the Shopify Admin.

The content you provide can be simple HTML elements or a `src` URL that will be loaded. When adding custom content, you can only provide a single parent element (commonly a `div` or `form`).
### _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)
- [Modal Component](/docs/api/app-bridge-library/react-components/modal-component)
- [ui-title-bar](/docs/api/app-bridge-library/web-components/ui-title-bar)
- [ui-save-bar](/docs/api/app-bridge-library/web-components/ui-save-bar)
## 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 `ui-modal` element and then opening it with the `show()` instance method or the `shopify.modal.show('modal-id')` API.
### Modals with different options

### Opening a max size Modal

```html
&lt;ui-modal id="my-modal" variant="max"&gt;
  &lt;div&gt;&lt;/div&gt;
  &lt;ui-title-bar&gt;
    &lt;button variant="primary"&gt;Primary action&lt;/button&gt;
    &lt;button&gt;Secondary action&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Specifying a Modal size

```html
&lt;ui-modal id="my-modal" variant="large"&gt;
  &lt;p&gt;Hello, World!&lt;/p&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Using a form in a Modal

```html
&lt;ui-modal id="my-modal" variant="max"&gt;
  &lt;form data-save-bar&gt;
    &lt;label&gt;
      Name:
      &lt;input name="submitted-name" autocomplete="name" /&gt;
    &lt;/label&gt;
    &lt;button&gt;Save&lt;/button&gt;
  &lt;/form&gt;
  &lt;ui-title-bar&gt;
    &lt;button variant="primary"&gt;Save&lt;/button&gt;
    &lt;button&gt;Cancel&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Specifying a title for the Modal

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;p&gt;Hello, World!&lt;/p&gt;
  &lt;ui-title-bar title="My Modal"&gt;&lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Adding primary and secondary actions to a Modal

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;p&gt;Hello, World!&lt;/p&gt;
  &lt;ui-title-bar&gt;
    &lt;button variant="primary" onclick="console.log('Saving')"&gt;Save&lt;/button&gt;
    &lt;button onclick="console.log('Cancelling')"&gt;Cancel&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Using a modal for a destructive action

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;p&gt;If you delete this resource, it can't be undone.&lt;/p&gt;
  &lt;ui-title-bar title="Delete this resource"&gt;
    &lt;button variant="primary" tone="critical" onclick="console.log('Deleting')"&gt;
      Delete
    &lt;/button&gt;
    &lt;button onclick="console.log('Cancelling')"&gt;Cancel&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Modal events

### Subscribing to Show

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;p&gt;Message&lt;/p&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

&lt;script&gt;
  document.getElementById('my-modal').addEventListener('show', () =&gt; {
    console.log('Modal is showing');
  });
&lt;/script&gt;

```


### Subscribing to Hide

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;div&gt;
    &lt;button onclick="document.getElementById('my-modal').hide()"&gt;
      Hide Modal
    &lt;/button&gt;
  &lt;/div&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Show Modal&lt;/button&gt;

&lt;script&gt;
  document.getElementById('my-modal').addEventListener('hide', () =&gt; {
    console.log('Modal is hiding');
  });
&lt;/script&gt;

```


### Updating the Modal once it is open

### Adding an element

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;div&gt;
    &lt;p&gt;Message&lt;/p&gt;
    &lt;button id="add-content"&gt;Add element&lt;/button&gt;
  &lt;/div&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

&lt;script&gt;
  const button = document.getElementById('add-content');
  button.addEventListener('click', () =&gt; {
    const p = document.createElement('p');
    p.textContent = 'Lorem ipsum';

    const modal = document.getElementById('my-modal');
    modal.content.appendChild(p);
  });
&lt;/script&gt;

```


### Updating the Modal variant

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;div&gt;
    &lt;p&gt;Message&lt;/p&gt;
    &lt;button id="add-content"&gt;Add element&lt;/button&gt;
  &lt;/div&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

&lt;script&gt;
  const button = document.getElementById('add-content');
  button.addEventListener('click', () =&gt; {
    const p = document.createElement('p');
    p.textContent = 'Lorem ipsum';

    const modal = document.getElementById('my-modal');
    modal.content.appendChild(p);
  });
&lt;/script&gt;

```


### Using a src URL to load content

### Loading content from a URL

```html
// main app
&lt;ui-modal id="my-modal" src="/my-route"&gt;
  &lt;ui-title-bar title="Title"&gt;
    &lt;button variant="primary"&gt;Label&lt;/button&gt;
    &lt;button onclick="document.getElementById('my-modal').hide()"&gt;Label&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&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;/body&gt;
&lt;/html&gt;

```


### Communicating between the Modal and the parent window

```html
// main app
&lt;script&gt;
  window.addEventListener('message', (ev) =&gt; {
    console.log('Message received in main app:', ev.data);
  });

  window.addEventListener('load', async () =&gt; {
    const modal = document.getElementById('src-modal');
    await modal.show();
    modal.contentWindow.postMessage('Hello from the main app', location.origin);
  });
&lt;/script&gt;

&lt;ui-modal id="my-modal" src="/my-route"&gt;
  &lt;ui-title-bar title="Title"&gt;
    &lt;button variant="primary"&gt;Label&lt;/button&gt;
    &lt;button onclick="document.getElementById('my-modal').hide()"&gt;Label&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&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;button
      onclick="window.opener.postMessage('Hello from the modal', location.origin)"
    &gt;
      Send message
    &lt;/button&gt;
    &lt;script&gt;
      window.addEventListener('message', (ev) =&gt; {
        console.log('Message received in modal:', ev.data);
      });
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;

```


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

```html
// main app
&lt;ui-modal src="/my-route" variant="max" id="my-modal"&gt;&lt;/ui-modal&gt;
&lt;button onclick="shopify.modal.show('my-modal')"&gt;Open&lt;/button&gt;
&lt;ui-modal id="my-nested-modal"&gt;
  &lt;p&gt;Message&lt;/p&gt;
&lt;/ui-modal&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;button onclick="window.opener.shopify.modal.show('my-nested-modal')"&gt;Open&lt;/button&gt;
  &lt;/body&gt;
&lt;/html&gt;
```


## ui-modal instance
The `ui-modal` element provides instance properties and methods to control the Modal.
### _UIModalElement

### addEventListener
Add 'show' | 'hide' event listeners.
### content
A getter/setter that is used to get the DOM content of the modal element and update the content after the modal has been opened.
### contentWindow
A getter that is used to get the Window object of the modal iframe when the modal is used with a `src` attribute. This can only be accessed when the modal is open, so it is recommended to use `await modal.show()` before accessing this property.
### hide
Hides the save bar element
### removeEventListener
Remove 'show' | 'hide' event listeners.
### show
Shows the save bar element
### src
A getter/setter that is used to set modal src.
### toggle
Toggles the save bar element between the showing and hidden states
### variant
A getter/setter that is used to set modal variant.
### Variant

'small' | 'base' | 'large' | 'max'
## Related
- [Modal](/docs/api/app-bridge-library/apis/modal)
- [Modal Component](/docs/api/app-bridge-library/react-components/modal-component)
- [ui-title-bar](/docs/api/app-bridge-library/web-components/ui-title-bar)
- [ui-save-bar](/docs/api/app-bridge-library/web-components/ui-save-bar)
## 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 `ui-modal` element and then opening it with the `show()` instance method or the `shopify.modal.show('modal-id')` API.
### Modals with different options

### Opening a max size Modal

```html
&lt;ui-modal id="my-modal" variant="max"&gt;
  &lt;div&gt;&lt;/div&gt;
  &lt;ui-title-bar&gt;
    &lt;button variant="primary"&gt;Primary action&lt;/button&gt;
    &lt;button&gt;Secondary action&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Specifying a Modal size

```html
&lt;ui-modal id="my-modal" variant="large"&gt;
  &lt;p&gt;Hello, World!&lt;/p&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Using a form in a Modal

```html
&lt;ui-modal id="my-modal" variant="max"&gt;
  &lt;form data-save-bar&gt;
    &lt;label&gt;
      Name:
      &lt;input name="submitted-name" autocomplete="name" /&gt;
    &lt;/label&gt;
    &lt;button&gt;Save&lt;/button&gt;
  &lt;/form&gt;
  &lt;ui-title-bar&gt;
    &lt;button variant="primary"&gt;Save&lt;/button&gt;
    &lt;button&gt;Cancel&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Specifying a title for the Modal

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;p&gt;Hello, World!&lt;/p&gt;
  &lt;ui-title-bar title="My Modal"&gt;&lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Adding primary and secondary actions to a Modal

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;p&gt;Hello, World!&lt;/p&gt;
  &lt;ui-title-bar&gt;
    &lt;button variant="primary" onclick="console.log('Saving')"&gt;Save&lt;/button&gt;
    &lt;button onclick="console.log('Cancelling')"&gt;Cancel&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Using a modal for a destructive action

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;p&gt;If you delete this resource, it can't be undone.&lt;/p&gt;
  &lt;ui-title-bar title="Delete this resource"&gt;
    &lt;button variant="primary" tone="critical" onclick="console.log('Deleting')"&gt;
      Delete
    &lt;/button&gt;
    &lt;button onclick="console.log('Cancelling')"&gt;Cancel&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

```


### Modal events

### Subscribing to Show

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;p&gt;Message&lt;/p&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

&lt;script&gt;
  document.getElementById('my-modal').addEventListener('show', () =&gt; {
    console.log('Modal is showing');
  });
&lt;/script&gt;

```


### Subscribing to Hide

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;div&gt;
    &lt;button onclick="document.getElementById('my-modal').hide()"&gt;
      Hide Modal
    &lt;/button&gt;
  &lt;/div&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Show Modal&lt;/button&gt;

&lt;script&gt;
  document.getElementById('my-modal').addEventListener('hide', () =&gt; {
    console.log('Modal is hiding');
  });
&lt;/script&gt;

```


### Updating the Modal once it is open

### Adding an element

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;div&gt;
    &lt;p&gt;Message&lt;/p&gt;
    &lt;button id="add-content"&gt;Add element&lt;/button&gt;
  &lt;/div&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

&lt;script&gt;
  const button = document.getElementById('add-content');
  button.addEventListener('click', () =&gt; {
    const p = document.createElement('p');
    p.textContent = 'Lorem ipsum';

    const modal = document.getElementById('my-modal');
    modal.content.appendChild(p);
  });
&lt;/script&gt;

```


### Updating the Modal variant

```html
&lt;ui-modal id="my-modal"&gt;
  &lt;div&gt;
    &lt;p&gt;Message&lt;/p&gt;
    &lt;button id="add-content"&gt;Add element&lt;/button&gt;
  &lt;/div&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&gt;

&lt;script&gt;
  const button = document.getElementById('add-content');
  button.addEventListener('click', () =&gt; {
    const p = document.createElement('p');
    p.textContent = 'Lorem ipsum';

    const modal = document.getElementById('my-modal');
    modal.content.appendChild(p);
  });
&lt;/script&gt;

```


### Using a src URL to load content

### Loading content from a URL

```html
// main app
&lt;ui-modal id="my-modal" src="/my-route"&gt;
  &lt;ui-title-bar title="Title"&gt;
    &lt;button variant="primary"&gt;Label&lt;/button&gt;
    &lt;button onclick="document.getElementById('my-modal').hide()"&gt;Label&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&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;/body&gt;
&lt;/html&gt;

```


### Communicating between the Modal and the parent window

```html
// main app
&lt;script&gt;
  window.addEventListener('message', (ev) =&gt; {
    console.log('Message received in main app:', ev.data);
  });

  window.addEventListener('load', async () =&gt; {
    const modal = document.getElementById('src-modal');
    await modal.show();
    modal.contentWindow.postMessage('Hello from the main app', location.origin);
  });
&lt;/script&gt;

&lt;ui-modal id="my-modal" src="/my-route"&gt;
  &lt;ui-title-bar title="Title"&gt;
    &lt;button variant="primary"&gt;Label&lt;/button&gt;
    &lt;button onclick="document.getElementById('my-modal').hide()"&gt;Label&lt;/button&gt;
  &lt;/ui-title-bar&gt;
&lt;/ui-modal&gt;

&lt;button onclick="document.getElementById('my-modal').show()"&gt;Open Modal&lt;/button&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;button
      onclick="window.opener.postMessage('Hello from the modal', location.origin)"
    &gt;
      Send message
    &lt;/button&gt;
    &lt;script&gt;
      window.addEventListener('message', (ev) =&gt; {
        console.log('Message received in modal:', ev.data);
      });
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;

```


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

```html
// main app
&lt;ui-modal src="/my-route" variant="max" id="my-modal"&gt;&lt;/ui-modal&gt;
&lt;button onclick="shopify.modal.show('my-modal')"&gt;Open&lt;/button&gt;
&lt;ui-modal id="my-nested-modal"&gt;
  &lt;p&gt;Message&lt;/p&gt;
&lt;/ui-modal&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;button onclick="window.opener.shopify.modal.show('my-nested-modal')"&gt;Open&lt;/button&gt;
  &lt;/body&gt;
&lt;/html&gt;
```