Migrate Button from Polaris React
Replace Polaris React Button with s-button. Decide first whether the call site performs an action, submits a form, navigates, downloads a file, or opens another component.
Anchor to Migrate a primary actionMigrate a primary action
This example preserves the button's hierarchy, label, and click behavior. Replace the imported Polaris React icon component with the documented Polaris web-component icon name.
Migrating a primary action with an icon
Polaris web components
export function AddProductButton({onAddProduct}) {
return (
<s-button variant="primary" icon="plus" onClick={onAddProduct}>
Add product
</s-button>
);
}Polaris React
import {Button} from '@shopify/polaris';
import {PlusIcon} from '@shopify/polaris-icons';
export function AddProductButton({onAddProduct}) {
return (
<Button variant="primary" icon={PlusIcon} onClick={onAddProduct}>
Add product
</Button>
);
}Preview
| Polaris React | Polaris web components | Migration notes |
|---|---|---|
onClick | onClick | Guard duplicate async requests in app logic. |
submit | type="submit" | Keep the button inside its native form. |
url | href | Use s-link for inline navigation; use button styling only when the hierarchy calls for it. |
external and target | target, commonly _blank | Preserve a real href; don't emulate navigation in onClick. |
download | download with href | Test the actual response and filename. |
loading | loading | Keep it true for the complete request and prevent repeat submission in app state. |
disabled | disabled | Explain unavailable prerequisites visibly; disabled controls aren't focusable. |
variant="primary" | variant="primary" | Keep one clear primary action for the current scope. |
| Plain or low-emphasis variants | variant="tertiary" | Re-evaluate hierarchy instead of copying appearance names. |
tone="critical" or destructive | tone="critical" | Use for destructive actions that are difficult to reverse. |
icon | A documented icon name string in icon | Remove Polaris React icon imports. |
iconOnly or no visible text | icon plus accessibilityLabel | Name the action, not the icon. |
disclosure | A trigger with commandFor pointing to s-menu or s-popover | Let the destination overlay own open and close state. |
pressed | Use the control that matches the state, such as s-switch or a choice field | Don't use an action button as a persistent setting. |
fullWidth | inlineSize="fill" | Let the button fill the available inline size only when the containing layout calls for it. |
size, textAlign, and monochrome | Containing layout and destination hierarchy | Remove appearance-only compatibility props. |
Anchor to Handle actions safelyHandle actions safely
Set loading before awaiting an operation, keep the label specific, and show success or failure feedback. Don't clear form values or navigate until persistence succeeds. For destructive changes, confirm scope in a modal and keep the critical action there.
Use commandFor when the button opens an s-menu, s-popover, s-modal, or another command target. Keep the target as a sibling with a stable id; don't retain React state that only opened the Polaris overlay.
Anchor to Test the migrationTest the migration
- Exercise enabled, disabled, loading, success, failure, and retry states.
- Submit with pointer, keyboard, and Enter from the form.
- Test internal links, external links, modified clicks, and downloads.
- Verify icon-only labels and focus order.
- Confirm destructive actions show the correct scope and can't run twice.
Anchor to Remove Polaris ReactRemove Polaris React
Remove Button, Polaris icon imports, disclosure state, and prop adapters after each call site is migrated. Remove @shopify/polaris only after no other route in scope imports it.