--- title: Modal description: >- The Modal component displays content in an overlay that shifts focus towards a specific action or set of information before the main flow can proceed. The library automatically applies the WAI-ARIA Dialog pattern to both the activator and the modal content. api_version: 2025-07 api_name: customer-account-ui-extensions source_url: html: >- https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/overlays/modal md: >- https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/overlays/modal.md --- Migrate to Polaris Version 2025-07 is the last API version to support React-based UI components. Later versions use [web components](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/polaris-web-components), native UI elements with built-in accessibility, better performance, and consistent styling with [Shopify's design system](https://shopify.dev/docs/apps/design). Check out the [migration guide](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components) to upgrade your extension. # Modal The Modal component displays content in an overlay that shifts focus towards a specific action or set of information before the main flow can proceed. The library automatically applies the [WAI-ARIA Dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/) to both the activator and the modal content. For contextual content that doesn't require full focus, use [Popover](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/overlays/popover) instead. ### Support Targets (25) ### Supported targets * Customer​Account::Kitchen​Sink * [customer-account.​footer.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/footer#footer-render-after-) * [customer-account.​order-index.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-index#order-index-targets) * [customer-account.​order-index.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-index#order-index-block-) * [customer-account.​order-status.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#order-status-announcement-) * [customer-account.​order-status.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#order-status-block-) * [customer-account.​order-status.​cart-line-item.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#cart-line-item-render-after-) * [customer-account.​order-status.​cart-line-list.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#cart-line-list-render-after-) * [customer-account.​order-status.​customer-information.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#customer-information-render-after-) * [customer-account.​order-status.​fulfillment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/fulfillment-status#fulfillment-status-targets) * [customer-account.​order-status.​payment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/payments-and-returns#payments-and-returns-targets) * [customer-account.​order-status.​return-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/payments-and-returns#return-details-render-after-) * [customer-account.​order-status.​unfulfilled-items.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/fulfillment-status#unfulfilled-items-render-after-) * [customer-account.​order.​action.​menu-item.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-actions#order-action-menu-item-) * [customer-account.​order.​action.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-actions#order-action-) * [customer-account.​order.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/full-page#order-specific-full-page-) * [customer-account.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/full-page#customer-account-full-page-) * [customer-account.​profile.​addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#profile-page-default-targets-) * [customer-account.​profile.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#announcement-) * [customer-account.​profile.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#profile-block-) * [customer-account.​profile.​company-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#profile-page-b2b-targets-) * [customer-account.​profile.​company-location-addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-addresses-render-after-) * [customer-account.​profile.​company-location-payment.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-payment-render-after-) * [customer-account.​profile.​company-location-staff.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-staff-render-after-) * customer-account.​profile.​payment.​render-after #### Use cases * **Confirmation dialogs:** Display confirmation prompts for destructive or irreversible actions like canceling a subscription. * **Policy display:** Present terms, return policies, or other important information that requires customer acknowledgment. * **Data entry:** Collect structured input through forms displayed in a modal with save and cancel actions. * **Detail previews:** Show detailed information or previews without navigating away from the current page. *** ## Properties Configure the following properties on the Modal component. * **accessibilityLabel** **string** A label that describes the purpose of the modal, announced by screen readers. If not set, it will use the value of `title`. * **id** **string** A unique identifier for the modal. When no `id` is set, a globally unique value will be used instead. * **onClose** **() => void** A callback fired when the modal is closed. This is triggered when the close button, the backdrop, or the `escape` key are pressed. * **onOpen** **() => void** A callback fired when the modal is opened. This is called at the beginning of the transition that opens the modal. * **padding** **boolean** Whether to add default spacing around both the header (which holds the `title`) and the content of the modal. * **primaryAction** **RemoteFragment** The primary action to perform, provided as a button component. Only one button can be rendered. * **secondaryActions** **RemoteFragment** The secondary actions to perform, provided as button components. Only one button can be rendered. * **size** **'small' | 'auto' | 'large' | 'max'** **Default: 'auto'** Adjust the size of the modal. * `'small'`: A compact modal for simple confirmations or short messages. * `'auto'`: Automatically sizes the modal based on its content. * `'large'`: A large modal for complex content or forms. * `'max'`: Expands the modal to its maximum size, on both the horizontal and vertical axes. * **title** **string** A title rendered at the top of the modal. *** ## Examples ### Display a return policy Present information that requires customer acknowledgment. This example shows a modal triggered by a link, with body text and a close button that calls `ui.overlay.close()`. ## Display a return policy ![A modal displaying a return policy with a close button.](https://shopify.dev/assets/assets/images/templated-apis-screenshots/checkout-ui-extensions/2025-07/modal-default-DRAx4DzM.png) ## Display a return policy ##### React ```tsx import { reactExtension, useApi, Button, Link, Modal, TextBlock, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.page.render', () => , ); function Extension() { const {ui} = useApi(); return ( We have a 30-day return policy, which means you have 30 days after receiving your item to request a return. To be eligible for a return, your item must be in the same condition that you received it, unworn or unused, with tags, and in its original packaging. You’ll also need the receipt or proof of purchase. } > Return policy ); } ``` ##### JS ```js import { extension, Button, Link, Modal, TextBlock, } from '@shopify/ui-extensions/customer-account'; export default extension('customer-account.page.render', (root, {ui}) => { const modalFragment = root.createFragment(); const modal = root.createComponent( Modal, {id: 'my-modal', title: 'Return policy', padding: true}, [ root.createComponent( TextBlock, undefined, 'We have a 30-day return policy, which means you have 30 days after receiving your item to request a return.', ), root.createComponent( TextBlock, undefined, 'To be eligible for a return, your item must be in the same condition that you received it, unworn or unused, with tags, and in its original packaging. You’ll also need the receipt or proof of purchase.', ), root.createComponent( Button, { onPress() { ui.overlay.close('my-modal'); }, }, 'Close', ), ], ); modalFragment.appendChild(modal); const link = root.createComponent( Link, {overlay: modalFragment}, 'Return policy', ); root.appendChild(link); }); ``` ### Confirm a destructive action Pair a cancel button with a destructive action button to prevent accidental operations. This example presents a subscription cancellation confirmation with keep and cancel options. ## Confirm a destructive action ##### React ```tsx import { reactExtension, useApi, Button, Modal, TextBlock, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.order-status.block.render', () => , ); function Extension() { const {ui} = useApi(); return ( } > Cancel subscription ); } ``` ##### JS ```js import { extension, Button, Modal, TextBlock, } from '@shopify/ui-extensions/customer-account'; export default extension( 'customer-account.order-status.block.render', (root, {ui}) => { const modalFragment = root.createFragment(); const modal = root.createComponent( Modal, {id: 'cancel-modal', title: 'Cancel subscription', padding: true}, [ root.createComponent( TextBlock, undefined, 'Are you sure you want to cancel your subscription? You\u2019ll lose access to all premium features at the end of your current billing period.', ), root.createComponent( Button, { onPress() { ui.overlay.close('cancel-modal'); }, }, 'Keep subscription', ), root.createComponent( Button, { onPress() { // Handle cancellation ui.overlay.close('cancel-modal'); }, }, 'Cancel subscription', ), ], ); modalFragment.appendChild(modal); const button = root.createComponent( Button, {overlay: modalFragment}, 'Cancel subscription', ); root.appendChild(button); }, ); ``` ### Collect input with a form Gather information without leaving the current context. This example embeds a feedback form with a select field and text area inside the modal. ## Collect input with a form ##### React ```tsx import { reactExtension, useApi, Button, Modal, Select, TextField, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.order-status.block.render', () => , ); function Extension() { const {ui} = useApi(); return (