Migrate BlockStack to the Polaris stack component
The Polaris stack component arranges children along the block or inline axis. It replaces the previous BlockStack component and is available as <s-stack> in API versions 2025-10 and newer. <s-stack> defaults to block direction, matching BlockStack. Note that gap defaults to 'none', whereas BlockStack spacing defaulted to 'base'. To preserve the previous spacing, set gap="base" explicitly.
Anchor to Updated propertiesUpdated properties
The following properties are different in the Polaris stack component.
Anchor to spacingspacing
The previous BlockStack spacing prop is now called gap, and the accepted values have changed. Use the following mapping to migrate deprecated tokens:
| Previous | New |
|---|---|
'none' | 'none' |
'extraTight' | 'small-400' |
'tight' | 'small-200' |
'base' | 'base' |
'loose' | 'large-200' |
'extraLoose' | 'large-500' |
The new token scale also adds 'small-500', 'small-300', 'small-100', 'small', 'large', 'large-100', 'large-300', and 'large-400'.
For more on the scale system, see Scale.
Migrating spacing to gap
Latest (Preact)
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
export default function extension() {
render(<Extension />, document.body);
}
function Extension() {
return (
<s-stack gap="base">
<s-text>First</s-text>
<s-text>Second</s-text>
</s-stack>
);
}Pre-Polaris (2025-07)
import {
reactExtension,
BlockStack,
Text,
} from '@shopify/ui-extensions-react/checkout';
export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);
function Extension() {
return (
<BlockStack spacing="base">
<Text>First</Text>
<Text>Second</Text>
</BlockStack>
);
}Anchor to inlineAlignmentinline Alignment
The previous BlockStack inlineAlignment prop is now called alignItems, which aligns children on the cross axis. The previous values ('start', 'center', 'end') are all still accepted, and alignItems also adds 'normal' and 'stretch'.
Anchor to cornerRadiuscorner Radius
The previous BlockStack cornerRadius prop is now called borderRadius, and the value format has changed.
| Change | Previous | New |
|---|---|---|
| Multi-corner syntax | Array of 2 or 4 values: ['base', 'none'] | Space-separated string: "base none" |
| Accepted values | 'none', 'small', 'base', 'large', 'fullyRounded' | 'none', 'small-100', 'small', 'base', 'large', 'large-100', 'max' |
fullyRounded is removed. Use max instead.
Anchor to borderborder
The previous BlockStack border shorthand controlled border style (for example, border="dotted"). On <s-stack>, border controls border size by default and accepts a token-based shorthand for size, color, and style:
| Pattern | Example | Description |
|---|---|---|
'{size}' | border="base" | Border size only. |
'{size} {color}' | border="base base" | Border size and color. |
'{size} {color} {style}' | border="base base dashed" | Border size, color, and style. |
| Previous value | New value | Migration notes |
|---|---|---|
'base' (single solid border) | border="base" | Renders a default-size border. |
'dotted' | border="base base dotted" | Specify size and color before style. |
'dashed' | border="base base dashed" | Specify size and color before style. |
'none' | border="none" or omit | No border. |
Anchor to borderWidthborder Width
The previous BlockStack borderWidth accepted 'base', 'medium', 'thick'. The Polaris stack borderWidth accepts a reduced keyword set: 'none', 'base', 'large', 'large-100', 'large-200'.
| Previous value | New value | Migration notes |
|---|---|---|
'base' | 'base' | No change needed. |
'medium' | 'large' | 'medium' is removed. |
'thick' | 'large-200' | 'thick' is removed. |
Anchor to displaydisplay
The previous BlockStack display values 'inline' and 'block' are no longer accepted. The Polaris stack display accepts 'auto' (the default) and 'none'.
| Previous value | New value | Migration notes |
|---|---|---|
'block' | 'auto' (the default) | Omit display for default block-level rendering. |
'inline' | Removed | Wrap inline content in <s-text> instead. This advice applies only when migrating display="inline" usages — direct text children of <s-stack> are still valid for non-inline content. |
'none' | 'none' | No change needed. |
Anchor to paddingpadding
The previous BlockStack padding prop's accepted values and multi-side shorthand format have changed.
Use the following mapping to migrate deprecated tokens:
| Previous | New |
|---|---|
'none' | 'none' |
'extraTight' | 'small-400' |
'tight' | 'small-200' |
'base' | 'base' |
'loose' | 'large-200' |
'extraLoose' | 'large-500' |
The new token scale also adds 'small-500', 'small-300', 'small-100', 'small', 'large', 'large-100', 'large-300', and 'large-400'.
For more on the scale system, see Scale.
The multi-side shorthand format has also changed:
| Previous | New |
|---|---|
Array of 2 or 4 values: ['base', 'none'] | Space-separated string with 1 to 4 values: "base none". The 3-value variant "block-start inline block-end" is also supported. |
To set only one axis, use paddingBlock or paddingInline instead of padding.
Anchor to SizesSizes
The size properties accept updated values in the Polaris stack component. Previous unitless number values map to pixels. For example, 300 is now '300px'.
| Property | Previous values | New values | Migration notes |
|---|---|---|---|
maxInlineSize | number | `${number}%` | 'fill' | `${number}px` | `${number}%` | '0' | 'none' | fill is removed. Use 100% instead. |
minInlineSize | number | `${number}%` | 'fill' | `${number}px` | `${number}%` | '0' | fill is removed. Use 100% instead. |
maxBlockSize | number | `${number}%` | 'fill' | `${number}px` | `${number}%` | '0' | 'none' | fill is removed. Use 100% instead. |
minBlockSize | number | `${number}%` | 'fill' | `${number}px` | `${number}%` | '0' | fill is removed. Use 100% instead. |
Anchor to accessibilityRoleaccessibility Role
Several accessibilityRole values have been renamed in the Polaris stack component. Update them to the new role names:
| Previous value | New value |
|---|---|
'complementary' | 'aside' |
'orderedList' | 'ordered-list' |
'unorderedList' | 'unordered-list' |
'listItem' | 'list-item' |
Other previously supported roles ('main', 'header', 'footer', 'section', 'navigation', 'separator', 'status', 'alert') are accepted unchanged. The Polaris stack also adds the following new roles:
| New role | Description |
|---|---|
'list-item-separator' | Separator between list items. |
'generic' | Generic container. |
'none' | No semantic role. |
If you used Style.default().when() to make this property responsive, container queries replace the Style helper. Wrap your content in <s-query-container> and use @container syntax in the property value. Learn more in Migrate StyleHelper to container queries.
If you used Style.default().when() to make this property responsive, container queries replace the Style helper. Wrap your content in <s-query-container> and use @container syntax in the property value. Learn more in Migrate StyleHelper to container queries.
Anchor to New propertiesNew properties
The Polaris stack component introduces the following new properties:
| New prop | Type | Description |
|---|---|---|
direction | 'block' | 'inline' | Sets the main axis. Defaults to block. |
blockSize | `${number}px` | `${number}%` | '0' | 'auto' | Adjusts the block size of the stack. |
inlineSize | `${number}px` | `${number}%` | '0' | 'auto' | Adjusts the inline size of the stack. |
justifyContent | 'normal' | 'space-between' | 'space-around' | 'space-evenly' | 'stretch' | 'center' | 'start' | 'end' | Aligns children on the main axis. |
alignContent | 'normal' | 'space-between' | 'space-around' | 'space-evenly' | 'stretch' | 'center' | 'start' | 'end' | Aligns wrapped rows on the cross axis. |