Migrate Backdrop from Polaris React
Polaris web components don't provide a standalone backdrop. Replace the complete overlay composition that owns the Polaris React Backdrop from @shopify/polaris with <s-modal> or <s-popover>.
The overlay component owns its backdrop or outside-click area, stacking, scroll behavior, keyboard dismissal, and focus management. Don't recreate those pieces with a fixed-position element.
Anchor to Choose the owning overlayChoose the owning overlay
| Existing use | Polaris web components | Migration notes |
|---|---|---|
| Dialog, confirmation, or focused form | s-modal | Provides a modal backdrop and traps focus while open. |
| Contextual content anchored to a button | s-popover | Dismisses when the merchant interacts outside it. |
| Contextual actions only | s-menu | Use instead of composing a backdrop with a custom action list. |
If Backdrop only covered the page during loading, remove it and use local loading states on the affected controls or content. Don't block the entire embedded app with an empty overlay.
Anchor to Replace the complete compositionReplace the complete composition
The following migration replaces a custom dialog and its Backdrop with s-modal. The trigger and close button target the modal by id; clicking the managed backdrop or pressing Escape also dismisses it.
Migrating Backdrop to an s-modal composition
Polaris web components
interface CustomerDetailsProps {
onClose(): void;
}
export function CustomerDetails({onClose}: CustomerDetailsProps) {
return (
<>
<s-button commandFor="customer-details">View customer</s-button>
<s-modal
id="customer-details"
heading="Maria Rodriguez"
onHide={onClose}
>
<s-text>Customer since April 2024</s-text>
<s-button
slot="secondary-actions"
commandFor="customer-details"
command="--hide"
>
Close
</s-button>
</s-modal>
</>
);
}Polaris React
import {Backdrop, Button} from '@shopify/polaris';
interface CustomerDetailsProps {
open: boolean;
onOpen(): void;
onClose(): void;
}
export function CustomerDetails({
open,
onOpen,
onClose,
}: CustomerDetailsProps) {
return (
<>
<Button onClick={onOpen}>View customer</Button>
{open && (
<>
<Backdrop onClick={onClose} />
<div
role="dialog"
aria-modal="true"
aria-labelledby="customer-details-heading"
>
<h2 id="customer-details-heading">Maria Rodriguez</h2>
<p>Customer since April 2024</p>
<button onClick={onClose}>Close</button>
</div>
</>
)}
</>
);
}Preview
Anchor to Removed propertiesRemoved properties
All Polaris React Backdrop properties are removed with the component.
There is no replacement property. s-modal, s-popover, and s-menu own their position in the Shopify admin's overlay stack. Remove app-defined z-index rules and don't try to place an overlay below the admin navigation from inside the iframe.
Anchor to transparenttransparent
There is no replacement property for changing the managed backdrop. Choose the overlay from the interaction instead:
- Use
s-modalwhen the rest of the interface must become inactive. - Use
s-popoverors-menufor anchored content that dismisses on outside interaction without a modal backdrop. - Keep content on the page when it doesn't need overlay behavior.
Anchor to onClickon Click
Don't move backdrop-click logic to a custom page layer. Use the overlay's hide event for logic that must run on every dismissal. In React, use onHide={handleClose}. This covers backdrop or outside clicks, Escape, and controls that use command="--hide".
The event doesn't distinguish a backdrop click from another dismissal. If an action must happen only after explicit confirmation, put it on a labeled button in the modal instead of running it when the backdrop is clicked.
There is no direct replacement. Pointer, touch, and keyboard dismissal are built into the owning overlay. Move business logic from onTouchStart to an explicit action, or to onHide when it applies to every close path.
Anchor to setClosingset Closing
Remove setClosing and any associated closing state. It coordinated the Polaris React backdrop's mouse-down and click sequence; Polaris web components manage their own dismissal and animation. Use afterhide when cleanup must wait until the overlay finishes hiding.
Anchor to Test the migrationTest the migration
- Open the overlay from its real trigger and verify focus moves into it.
- Dismiss it by backdrop or outside click, Escape, and every close button.
- Confirm
onHidelogic runs once for each supported close path. - Verify focus returns to the trigger and the page doesn't remain scroll-locked.
- Test long and scrollable content at narrow iframe sizes.
- Remove custom portal, z-index, scroll-lock, and focus-trap code that only supported the old backdrop.
- Remove the Polaris React
Backdropimport after its final consumer is migrated.