Migrate to the Polaris choice list component
The Polaris choice list component groups related <s-choice> elements and renders them as radio buttons or checkboxes. It replaces the previous ChoiceList component and is available as <s-choice-list> in API versions 2025-10 and newer.
Anchor to Updated propertiesUpdated properties
The following properties are different in the Polaris choice list component.
Anchor to variantvariant
The previous ChoiceList variant prop values have changed.
| Previous value | New value | Migration notes |
|---|---|---|
'base' | 'list' | 'list' is the equivalent. |
'group' | 'block', 'inline', 'grid', or 'list' | Choose the layout variant that best matches your use case. |
| Default | 'auto' | 'auto' is the new default, which picks the layout automatically. |
Anchor to valuevalue
The previous ChoiceList value prop maps to per-child selected on each <s-choice>. Set selected={true} on the choices that should be selected, and read the current selection in onChange from event.currentTarget.values, which is always a string[].
Use the new multiple attribute to switch between single and multiple selection — the mode is no longer inferred from the value type.
You can also set values on <s-choice-list> as a shortcut for setting selected on the matching children.
Migrating single selection
Latest (Preact)
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
import {useState} from 'preact/hooks';
export default function extension() {
render(<Extension />, document.body);
}
function Extension() {
const [shipping, setShipping] = useState('express');
return (
<s-choice-list
name="shipping"
onChange={(event) => setShipping(event.currentTarget.values[0])}
>
<s-choice value="express" selected={shipping === 'express'}>
Express
</s-choice>
<s-choice value="standard" selected={shipping === 'standard'}>
Standard
</s-choice>
</s-choice-list>
);
}Pre-Polaris (2025-07)
import {
reactExtension,
ChoiceList,
Choice,
} from '@shopify/ui-extensions-react/checkout';
import {useState} from 'react';
export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);
function Extension() {
const [shipping, setShipping] = useState('express');
return (
<ChoiceList
name="shipping"
value={shipping}
onChange={(value) => setShipping(value)}
>
<Choice id="express">Express</Choice>
<Choice id="standard">Standard</Choice>
</ChoiceList>
);
}For uncontrolled selection, swap selected for defaultSelected on each <s-choice>.
Migrating multiple selection
Latest (Preact)
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
import {useState} from 'preact/hooks';
export default function extension() {
render(<Extension />, document.body);
}
function Extension() {
const [features, setFeatures] = useState(['feature1', 'feature2']);
return (
<s-choice-list
name="features"
multiple
onChange={(event) => setFeatures(event.currentTarget.values)}
>
<s-choice value="feature1" selected={features.includes('feature1')}>
Feature 1
</s-choice>
<s-choice value="feature2" selected={features.includes('feature2')}>
Feature 2
</s-choice>
<s-choice value="feature3" selected={features.includes('feature3')}>
Feature 3
</s-choice>
</s-choice-list>
);
}Pre-Polaris (2025-07)
import {
reactExtension,
BlockStack,
ChoiceList,
Choice,
} from '@shopify/ui-extensions-react/checkout';
import {useState} from 'react';
export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);
function Extension() {
const [features, setFeatures] = useState(['feature1', 'feature2']);
return (
<ChoiceList
name="features"
value={features}
onChange={(values) => setFeatures(values)}
>
<BlockStack>
<Choice id="feature1">Feature 1</Choice>
<Choice id="feature2">Feature 2</Choice>
<Choice id="feature3">Feature 3</Choice>
</BlockStack>
</ChoiceList>
);
}Anchor to onChangeon Change
The previous ChoiceList onChange prop now receives an Event instead of the selected value(s). Read the current selection from event.currentTarget.values, which is always a string[].
Anchor to New propertiesNew properties
The Polaris choice list component introduces the following new properties:
| New prop | Type | Description |
|---|---|---|
label | string | Sets the label text for the choice list. |
labelAccessibilityVisibility | 'visible' | 'exclusive' | Controls the visibility of the label. Defaults to 'visible'. |
disabled | boolean | Disables all choices in the list. |
error | string | Sets the error message to display. |
id | string | Sets a unique identifier for the choice list. |
multiple | boolean | Renders the choices as checkboxes when true, or as radio buttons when false. |