Migrate to the Polaris button component
The Polaris button component triggers actions and navigation. It replaces the previous Button component and is available as <s-button> in API versions 2025-10 and newer.
Anchor to Updated propertiesUpdated properties
The following properties are different in the Polaris button component.
Anchor to onPresson Press
The previous Button onPress prop is now called onClick.
The previous Button to prop is now called href.
Anchor to appearanceappearance
The previous Button appearance prop is now called tone.
| Previous value | New value | Migration notes |
|---|---|---|
| Default (no value) | 'auto' | 'auto' is the new default. |
'critical' | 'critical' | No change needed. |
'monochrome' | Removed | monochrome is no longer available. 'neutral' is the closest alternative, but the behavior isn't identical. |
Anchor to kindkind
The previous Button kind prop is now called variant.
| Previous value | New value | Migration notes |
|---|---|---|
| Default (primary) | 'auto' | The default changed from 'primary' to 'auto'. |
'primary' | 'primary' | No change needed. |
'secondary' | 'secondary' | No change needed. |
'plain' | Removed | Use <s-link> instead. |
Migrating kind to variant
Latest (Preact)
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
export default function extension() {
render(<Extension />, document.body);
}
function Extension() {
return (
<s-button variant="secondary">
Cancel
</s-button>
);
}Pre-Polaris (2025-07)
import {
reactExtension,
Button,
} from '@shopify/ui-extensions-react/checkout';
export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);
function Extension() {
return (
<Button kind="secondary">
Cancel
</Button>
);
}Migrating kind='plain' to s-link
Latest (Preact)
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
export default function extension() {
render(<Extension />, document.body);
}
function Extension() {
return (
<s-link href="/details">
View details
</s-link>
);
}Pre-Polaris (2025-07)
import {
reactExtension,
Button,
} from '@shopify/ui-extensions-react/checkout';
export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);
function Extension() {
return (
<Button kind="plain" to="/details">
View details
</Button>
);
}Anchor to submit and accessibilityRole="submit"submit and accessibility Role="submit"
The previous Button submit prop and accessibilityRole="submit" have been replaced with type="submit".
| Previous pattern | New pattern | Migration notes |
|---|---|---|
submit={true} | type="submit" | Use type prop. |
accessibilityRole="submit" | type="submit" | Use type prop. |
Anchor to Removed propertiesRemoved properties
The previous Button toggles, activateAction, and activateTarget props have been replaced with command and commandFor.
| Previous pattern | New pattern | Migration notes |
|---|---|---|
toggles="modal-id" | command="--toggle" + commandFor="modal-id" | Toggle behavior for modals, sheets, etc. |
activateAction="copy" + activateTarget="element-id" | command="--copy" + commandFor="element-id" | Copy behavior now uses the command pattern. |
Migrating activateAction to command
Latest (Preact)
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
export default function extension() {
render(<Extension />, document.body);
}
function Extension() {
return (
<>
<s-button command="--copy" commandFor="promo-code">
Copy promo code
</s-button>
<s-clipboard-item id="promo-code" text="SAVE25"></s-clipboard-item>
</>
);
}Pre-Polaris (2025-07)
import {
reactExtension,
Button,
ClipboardItem,
} from '@shopify/ui-extensions-react/checkout';
export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);
function Extension() {
return (
<>
<Button activateAction="copy" activateTarget="promo-code">
Copy promo code
</Button>
<ClipboardItem id="promo-code" text="SAVE25" />
</>
);
}Anchor to Combining toggle and copyCombining toggle and copy
The previous Button accepted both toggles (to show an overlay like a tooltip) and activateAction (to copy a value) on the same element. With the new command pattern, command accepts a single action. To copy a value and surface a tooltip from the same button, use command="--copy" for the copy action and interestFor to show a sibling <s-tooltip> on hover and focus.
Migrating combined toggles and activateAction
Latest (Preact)
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
export default function extension() {
render(<Extension />, document.body);
}
function Extension() {
return (
<>
<s-button
command="--copy"
commandFor="promo-code"
interestFor="copy-tooltip"
>
Copy promo code
</s-button>
<s-tooltip id="copy-tooltip">Copies SAVE25 to the clipboard</s-tooltip>
<s-clipboard-item id="promo-code" text="SAVE25"></s-clipboard-item>
</>
);
}Pre-Polaris (2025-07)
import {
reactExtension,
Button,
ClipboardItem,
Tooltip,
} from '@shopify/ui-extensions-react/checkout';
export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);
function Extension() {
return (
<>
<Button
toggles="copy-tooltip"
activateAction="copy"
activateTarget="promo-code"
overlay={
<Tooltip id="copy-tooltip">
Copies SAVE25 to the clipboard
</Tooltip>
}
>
Copy promo code
</Button>
<ClipboardItem id="promo-code" text="SAVE25" />
</>
);
}Anchor to loadingLabelloading Label
The Polaris button component no longer supports loadingLabel. Loading state accessibility is handled automatically.
Anchor to inlineAlignmentinline Alignment
The Polaris button component no longer supports inlineAlignment. The previous Button filled its container by default, and inlineAlignment aligned the button's content within that full-width control. The Polaris button defaults to intrinsic width (inlineSize="auto"), so to preserve the previous behavior, set inlineSize="fill" and wrap the button's children in <s-stack> using justifyContent to align the content. There isn't a dedicated content-alignment prop on <s-button>, so the nested stack is the recommended pattern.
'fill' on <s-button> vs. <s-box><s-button> keeps the 'fill' keyword for inlineSize. This differs from <s-box>, where 'fill' is removed in favor of '100%'. Each component's accepted values are documented on its own reference page.
<s-button> keeps the 'fill' keyword for inlineSize. This differs from <s-box>, where 'fill' is removed in favor of '100%'. Each component's accepted values are documented on its own reference page.
Migrating inlineAlignment to a content stack
Latest (Preact)
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
export default function extension() {
render(<Extension />, document.body);
}
function Extension() {
return (
<s-button inlineSize="fill">
<s-stack direction="inline" justifyContent="end" minInlineSize="100%">
Pay now
</s-stack>
</s-button>
);
}Pre-Polaris (2025-07)
import {
reactExtension,
Button,
Text,
} from '@shopify/ui-extensions-react/checkout';
export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);
function Extension() {
return (
<Button inlineAlignment="end">
<Text>Pay now</Text>
</Button>
);
}Anchor to overlayoverlay
The Polaris button component no longer supports overlay. Render the overlay as a sibling element with an id and wire the trigger to it. The migration pattern depends on what kind of overlay you're showing:
- For modals, sheets, and popovers (click-activated overlays): use
commandandcommandForon the trigger. - For tooltips (hover/focus-activated overlays): use
interestForon the trigger pointing to a sibling<s-tooltip id="...">. See the tooltip migration guide for details.
The example below shows the modal case.
Migrating overlay to command
Latest (Preact)
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
export default function extension() {
render(<Extension />, document.body);
}
function Extension() {
return (
<>
<s-button command="--show" commandFor="details-modal">
More info
</s-button>
<s-modal id="details-modal" heading="Details">
<s-paragraph>Delivery in 2 to 4 business days.</s-paragraph>
</s-modal>
</>
);
}Pre-Polaris (2025-07)
import {
reactExtension,
Button,
Modal,
Text,
} from '@shopify/ui-extensions-react/checkout';
export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);
function Extension() {
return (
<Button
overlay={
<Modal id="details-modal" title="Details">
<Text>Delivery in 2 to 4 business days.</Text>
</Modal>
}
>
More info
</Button>
);
}Anchor to New propertiesNew properties
The Polaris button component introduces the following new properties:
| New prop | Type | Description |
|---|---|---|
command | '--auto' | '--toggle' | '--copy' | '--show' | '--hide' | Sets the action to run when the button is activated. |
commandFor | string | Sets the ID of the target component for the command. |
inlineSize | 'auto' | 'fill' | 'fit-content' | Controls the button's inline size. Defaults to 'auto'. |
target | 'auto' | '_blank' | Controls where a linked URL opens when href is used. |
interestFor | string | Sets the ID of the component that should respond to hover and focus. |
Anchor to inlineSizeinline Size
The previous Button component filled the available inline space by default. The Polaris button component defaults to 'auto' sizing. Set inlineSize='fill' to match the previous behavior.
| Previous value | New value | Migration notes |
|---|---|---|
| Default (fill) | 'auto' | Set inlineSize='fill' to preserve the previous behavior. |