Migrate Portal from Polaris React
Keep a framework portal only for custom UI that genuinely must escape its container. Polaris web component overlays manage their own rendering and don't need a Polaris portal.
Anchor to Choose the destinationChoose the destination
| Polaris React | Polaris web components | Migration type |
|---|---|---|
Portal | Keep the framework portal only for custom UI. Polaris overlays don't require it. | Native DOM |
Anchor to Map portal responsibilitiesMap portal responsibilities
| Polaris React usage | Polaris web components | Migration notes |
|---|---|---|
| Modal content | s-modal | Render normally and connect its trigger with commandFor. |
| Popover content | s-popover | Let the component manage placement, stacking, and dismissal. |
Arbitrary content moved to document.body | Render in document flow or review the custom overlay separately | Preserve focus order, clipping, and cleanup. |
Anchor to Migrate the call siteMigrate the call site
-
Locate why
Portalis used and the exact element or event target it controls. -
Implement the native DOM behavior in the framework lifecycle that owns that target.
-
Add cleanup and protect against targets that aren't mounted.
-
After verification, remove the
Portalimport and any Polaris-only state, wrappers, or helpers that no longer have a caller.
Anchor to Preserve these behaviorsPreserve these behaviors
- The original trigger and target of the behavior.
- Framework mount, update, and cleanup timing.
- Focus and keyboard behavior where relevant, without unexpected global side effects.
Anchor to Test and remove Polaris ReactTest and remove Polaris React
Test the migrated Portal behavior through its user-visible outcome. Verify timing, focus or keyboard behavior, repeated mounts, missing targets, and cleanup on unmount.
Don't remove @shopify/polaris while another component still imports it. Once all call sites are migrated, remove the package and its provider-level setup, then run the app's full test suite.