> Note:
> This is a legacy API. Use the latest version of [`Modal`](/docs/api/app-bridge-library/web-components/ui-modal) instead.
Modals are overlays that prevent users from interacting with the rest of the app until they take an action that dismisses the modal.
Modals can be disruptive because they require users to take an action before they can continue interacting with the rest of Shopify. You should use modals sparingly.
The `Modal` action set allows you to open two types of modal: message and iframe. Message modals support only plain text content. Iframe modals allow you to fully customize the modal contents.
There are 2 ways to use the modal action:
1. [Plain JavaScript](#plain-javascript)
2. [React component](#react)
## Plain JavaScript
### Example code
Import the `createApp` function from `@shopify/app-bridge` and the `Modal` from `@shopify/app-bridge/actions`. Then use the `createApp` function to create an app.
> Note
> In the following example, `config` is a valid App Bridge configuration object. Learn more about [configuring App Bridge](/docs/api/app-bridge/previous-versions/app-bridge-from-npm/app-setup#initialize-shopify-app-bridge-in-your-app).
```js
import createApp from '@shopify/app-bridge';
import {Modal} from '@shopify/app-bridge/actions';
const app = createApp(config);
```
### Create a message modal
Create a message modal using the `message` option. Message modals support plain text content of any length.
```js
const modalOptions = {
title: 'My Modal',
message: 'Hello world!',
};
const myModal = Modal.create(app, modalOptions);
```
### Create an iframe modal
Create an iframe modal by passing the `url` option. If the `url` option is present, then the `message` option will be ignored.
### Create an iframe modal with an absolute URL
```js
const modalOptions = {
title: 'My Modal',
url: 'http://example.com',
};
const myModal = Modal.create(app, modalOptions);
```
> Note
> The absolute url option allows you to specify a sub domain, but not a different domain from the app url.
### Create an iframe modal with a relative path
A relative path iframe sets the URL relative to your app root.
```js
const modalOptions = {
title: 'My Modal',
path: '/settings',
};
const myModal = Modal.create(app, modalOptions);
```
If your app’s root URL was `https://myapp.com`, then the example above would open a modal at `https://myapp.com/settings`.
### Open and close a modal
Open and close the modal by dispatching the `OPEN` and `CLOSE` actions.
```js
const modalOptions = {
title: 'My Modal',
url: 'http://example.com',
};
const myModal = Modal.create(app, modalOptions);
myModal.dispatch(Modal.Action.OPEN);
// Close modal
myModal.dispatch(Modal.Action.CLOSE);
```
### Add footer buttons
Add buttons to the modal footer. All modals support one primary button and multiple secondary buttons. To learn more about buttons, refer to [Button](/docs/api/app-bridge/previous-versions/actions/button).
```js
const okButton = Button.create(app, {label: 'Ok'});
okButton.subscribe(Button.Action.CLICK, () => {
// Do something with the click action
});
const cancelButton = Button.create(app, {label: 'Cancel'});
cancelButton.subscribe(Button.Action.CLICK, () => {
// Do something with the click action
});
const modalOptions = {
title: 'My Modal',
message: 'Hello world!',
footer: {
buttons: {
primary: okButton,
secondary: [cancelButton],
},
},
};
const myModal = Modal.create(app, modalOptions);
```
### Subscriptions
Subscribe to modal actions by calling `subscribe`. This returns a function that you can call to unsubscribe from the action.
```js
const modalOptions = {
title: 'My Modal',
url: 'http://example.com',
};
const myModal = Modal.create(app, modalOptions);
const openUnsubscribe = myModal.subscribe(Modal.Action.OPEN, () => {
// Do something with the open event
});
const closeUnsubscribe = myModal.subscribe(Modal.Action.CLOSE, () => {
// Do something with the close event
});
// Unsubscribe to actions
openUnsubscribe();
closeUnsubscribe();
```
All [action sets](/docs/api/app-bridge/previous-versions/actions#action-sets) in App Bridge support the same subscribe API. The modal footer buttons also return an unsubscribe function.
```js
const okButton = Button.create(app, {label: 'Ok'});
const okButtonUnsubscribe = okButton.subscribe(Button.Action.CLICK, () => {
// Do something with the click action
});
okButtonUnsubscribe();
```
### Unsubscribe from all
Call `unsubscribe` to remove all subscriptions on the modal and its children (including buttons).
```js
const okButton = Button.create(app, {label: 'Ok'});
okButton.subscribe(Button.Action.CLICK, () => {
// Do something with the click action
});
const cancelButton = Button.create(app, {label: 'Cancel'});
cancelButton.subscribe(Button.Action.CLICK, () => {
// Do something with the click action
});
const modalOptions = {
title: 'My Modal',
url: 'http://example.com',
footer: {
buttons: {
primary: okButton,
secondary: [cancelButton],
},
},
};
const myModal = Modal.create(app, modalOptions);
myModal.subscribe(Modal.Action.OPEN, () => {
// Do something with the open event
});
myModal.subscribe(Modal.Action.CLOSE, () => {
// Do something with the close event
});
// Unsubscribe from modal open and close actions
// Unsubscribe from okButton and cancelButton click actions
myModal.unsubscribe();
```
### Unsubscribe from only modal actions
Call `unsubscribe` with `false` to remove only modal subscriptions while leaving child subscriptions intact. For example, you might want to unsubscribe from the modal but keep button listeners so that you can reuse the buttons in a different modal.
```js
const okButton = Button.create(app, {label: 'Ok'});
okButton.subscribe(Button.Action.CLICK, () => {
// Do something with the click action
});
const cancelButton = Button.create(app, {label: 'Cancel'});
cancelButton.subscribe(Button.Action.CLICK, () => {
// Do something with the click action
});
const modalOptions = {
title: 'My Modal',
message: 'Hello world!',
footer: {
buttons: {
primary: okButton,
secondary: [cancelButton],
},
},
};
const myModal = Modal.create(app, modalOptions);
// Unsubscribe from only modal open and close actions
myModal.unsubscribe(false);
// You can reuse the buttons above in a new modal
// Their subscriptions will be left intact
const newModalOptions = {
title: 'Confirm',
message: 'Are you sure?',
footer: {
buttons: {
primary: okButton,
secondary: [cancelButton],
},
},
};
const confirmModal = Modal.create(app, newModalOptions);
```
### Update options
Call the `set` method with partial modal options to update the options of an existing modal. This automatically triggers the `UPDATE` action on the modal and merges the given options with the existing options.
```js
const modalOptions = {
title: 'My Modal',
url: 'http://example.com',
};
const myModal = Modal.create(app, modalOptions);
myModal.set({title: 'My new title'});
```
### Update footer buttons
Update buttons attached to a modal's footer. Any updates made to the modal's footer buttons automatically trigger an `UPDATE` action on the modal.
```js
const okButton = Button.create(app, {label: 'Ok'});
const cancelButton = Button.create(app, {label: 'Cancel'});
const modalOptions = {
title: 'My Modal',
message: 'Hello world!',
footer: {
buttons: {
primary: okButton,
secondary: [cancelButton],
},
},
};
const myModal = Modal.create(app, modalOptions);
myModal.dispatch(Modal.Action.OPEN);
okButton.set({label: 'Good to go!'});
```
### Set modal size
By default, modals have a fixed size of `Small`. You can customize the size of a modal by passing in a different `Modal.Size` value.
```js
const modalOptions = {
title: 'My Modal',
message: 'Hello world!',
size: Modal.Size.Large,
};
const myModal = Modal.create(app, modalOptions);
myModal.dispatch(Modal.Action.OPEN);
```
The 3 values for `Modal.Size` are `Small`, `Medium` and `Large`.
> Note
> The full screen modal size has been deprecated in version 1.6.5. If you open a modal with the size set to `Full`, then it will display in the default size of `Medium`.
> Note
> The `Auto` modal size has been deprecated in version 1.12.x and moved into the `setupModalAutoSizing` utility. If you open a modal with the size set to `Auto`, then it will default to size `Medium`.
### Set modal size automatically
The `setupModalAutoSizing` utility allows your iframe modal to update its height to fit the page content.
In your main app, open an iframe modal:
```js
import createApp from '@shopify/app-bridge';
import {Modal} from '@shopify/app-bridge/actions';
import {setupModalAutoSizing} from '@shopify/app-bridge/utilities';
const app = createApp({
apiKey: '12345',
});
const modalOptions = {
title: 'My Modal',
path: '/modal',
};
const myModal = Modal.create(app, modalOptions);
myModal.dispatch(Modal.Action.OPEN);
```
Inside the modal page, import the `setupModalAutoSizing` utility to enable auto sizing:
```js
import createApp from '@shopify/app-bridge';
import {setupModalAutoSizing} from '@shopify/app-bridge/utilities';
const app = createApp({
apiKey: '12345',
});
setupModalAutoSizing(app);
```
Avoid setting `height`, `margin` or `padding` styles on the `