Skip to main content
Migrate to Polaris

Version 2025-07 is the last API version to support React-based UI components. Later versions use web components, native UI elements with built-in accessibility, better performance, and consistent styling with Shopify's design system. Check out the migration guide to upgrade your extension.

ChoiceList

Use the ChoiceList component to present a list of choices where buyers can make a single selection or multiple selections.

Support
Targets (50)

Supported targets


string
required

A unique identifier for the field in the closest Form component.

Anchor to onChange
onChange
(value: T) => void
required

A callback fired when the choice list value changes. This callback is called with a string or array of strings indicating the ids of choices that should now be selected. This component is controlled, so you must store this value in state and reflect it back in the value prop.

Anchor to value
value
T
required

A string or string[] indicating the ids of selected choices. When a string is set, choices render as radios. When a string array is set, choices render as checkboxes.

Anchor to variant
variant
'base' | 'group'
Default: 'base'

Toggle between base and group look.

Check the best practices to learn more about the variants.


Basic ChoiceList

Example

Basic ChoiceList

import {
reactExtension,
BlockStack,
Choice,
ChoiceList,
Icon,
InlineStack,
} from '@shopify/ui-extensions-react/checkout';

export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);

function Extension() {
return (
<InlineStack>
<ChoiceList
name="group-single"
variant="group"
value="ship"
onChange={(value) => {
console.log(
`onChange event with value: ${value}`,
);
}}
>
<Choice
secondaryContent={
<Icon source="truck" />
}
id="ship"
>
Ship
</Choice>
<Choice
secondaryContent={
<Icon source="marker" />
}
id="ship-to-pickup-point"
>
Ship to pickup point
</Choice>
<Choice
secondaryContent={
<Icon source="store" />
}
id="pick-up"
>
Pick up in store
</Choice>
</ChoiceList>
<ChoiceList
name="base-multiple"
value={['remember-me']}
onChange={(value) => {
console.log(
`onChange event with value: ${value}`,
);
}}
>
<BlockStack>
<Choice id="remember-me">
Save this information for next time
</Choice>
<Choice id="email-me">
Email me with news and offers
</Choice>
<Choice id="text-me">
Text me with news and offers
</Choice>
</BlockStack>
</ChoiceList>
</InlineStack>
);
}
import {
extension,
InlineStack,
ChoiceList,
Choice,
BlockStack,
Icon,
} from '@shopify/ui-extensions/checkout';

export default extension('purchase.checkout.block.render', (root) => {
const inlineStack = root.createComponent(InlineStack, undefined, [
root.createComponent(
ChoiceList,
{
name: 'group-single',
variant: 'group',
value: 'ship',
onChange: (value) => {
console.log(`onChange event with value: ${value}`);
},
},
[
root.createComponent(
Choice,
{
secondaryContent: root.createComponent(Icon, {source: 'truck'}),
id: 'ship',
},
'Ship',
),
root.createComponent(
Choice,
{
secondaryContent: root.createComponent(Icon, {source: 'marker'}),
id: 'ship-to-pickup-point',
},
'Ship to pickup point',
),
root.createComponent(
Choice,
{
secondaryContent: root.createComponent(Icon, {source: 'store'}),
id: 'pick-up',
},
'Pick up in store',
),
],
),
root.createComponent(
ChoiceList,
{
name: 'base-multiple',
value: ['remember-me'],
onChange: (value) => {
console.log(`onChange event with value: ${value}`);
},
},
[
root.createComponent(BlockStack, undefined, [
root.createComponent(
Choice,
{id: 'remember-me'},
'Save this information for next time',
),
root.createComponent(
Choice,
{id: 'email-me'},
'Email me with news and offers',
),
root.createComponent(
Choice,
{id: 'text-me'},
'Text me with news and offers',
),
]),
],
),
]);

root.appendChild(inlineStack);
});

Anchor to Custom survey using the base variantCustom survey using the base variant

The base variant’s flexibility allows for the creation of Likert scales using the ChoiceList component. By utilizing layout components, you can easily structure rows and columns for this purpose.

Custom survey using the base variant

The base variant’s flexibility allows for the creation of Likert scales using the ChoiceList component. By utilizing layout components, you can easily structure rows and columns for this purpose.

Custom survey using the base variant

import {
reactExtension,
Choice,
ChoiceList,
Grid,
TextBlock,
View,
} from '@shopify/ui-extensions-react/checkout';

export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);

function Extension() {
return (
<Grid
columns={[
'fill',
'13%',
'13%',
'13%',
'13%',
'13%',
]}
rows="auto"
spacing="none"
border="base"
cornerRadius="base"
overflow="hidden"
>
<View />
<View
padding={['tight', 'extraTight']}
blockAlignment="center"
accessibilityVisibility="hidden"
import {
extension,
Choice,
ChoiceList,
Grid,
TextBlock,
View,
} from '@shopify/ui-extensions/checkout';

export default extension(
'purchase.checkout.block.render',
(root) => {
const grid = root.createComponent(
Grid,
{
columns: [
'fill',
'13%',
'13%',
'13%',
'13%',
'13%',
],
rows: 'auto',
spacing: 'none',
border: 'base',
cornerRadius: 'base',
overflow: 'hidden',
},
[
root.createComponent(View, {}, []),
root.createComponent(
View,
{
padding: ['tight', 'extraTight'],
blockAlignment: 'center',

Anchor to Collecting additional informationCollecting additional information

The ChoiceList component’s group variant, combined with the details property, allows for the conditional display of information when needed.

Collecting additional information

The ChoiceList component’s group variant, combined with the details property, allows for the conditional display of information when needed.

Collecting additional information

import {
reactExtension,
BlockStack,
Choice,
ChoiceList,
DatePicker,
TextBlock,
TextField,
View,
} from '@shopify/ui-extensions-react/checkout';

export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);

function Extension() {
return (
<ChoiceList
variant="group"
name="white-glove"
value={['white-glove-1']}
onChange={(value) => {
console.log(
`onChange event with value: ${value}`,
);
}}
>
<Choice
id="white-glove-1"
details={
<>
<BlockStack spacing="base">
<BlockStack spacing="extraTight">
<TextBlock>
Choose a delivery date
</TextBlock>
<View
background="base"
border="base"
cornerRadius="base"
padding="base"
>
<DatePicker selected="" />
</View>
</BlockStack>
<BlockStack spacing="extraTight">
<TextField
label="Additional instructions"
value=""
/>
<TextBlock
appearance="subdued"
size="small"
>
The more detailed the delivery
instructions are, the best we
can make the delivery experience
for you.
</TextBlock>
</BlockStack>
</BlockStack>
</>
}
>
Use white glove delivery service
</Choice>
</ChoiceList>
);
}
import {
extension,
BlockStack,
Choice,
ChoiceList,
DatePicker,
TextBlock,
TextField,
View,
} from '@shopify/ui-extensions/checkout';

export default extension(
'purchase.checkout.block.render',
(root) => {
const choiceList = root.createComponent(
ChoiceList,
{
name: 'white-glove',
value: ['white-glove-1'],
onChange: (nextValue) => {
console.log(
`onChange event with value: ${nextValue}`,
);
},
},
[
root.createComponent(
Choice,
{id: 'white-glove-1'},
[
root.createComponent(
BlockStack,
{spacing: 'base'},
[
root.createComponent(
BlockStack,
{spacing: 'extraTight'},
[
root.createComponent(
TextBlock,
{},
'Choose a delivery date',
),
root.createComponent(
View,
{
background: 'base',
border: 'base',
cornerRadius: 'base',
padding: 'base',
},
root.createComponent(
DatePicker,
{selected: ''},
),
),
],
),
root.createComponent(
BlockStack,
{spacing: 'extraTight'},
[
root.createComponent(
TextField,
{
label:
'Additional instructions',
value: '',
},
),
root.createComponent(
TextBlock,
{
appearance: 'subdued',
size: 'small',
},
'The more detailed the delivery instructions are, the best we can make the delivery experience for you.',
),
],
),
],
),
],
),
],
);

root.appendChild(choiceList);
},
);

Anchor to Displaying a short list of time choicesDisplaying a short list of time choices

The ChoiceList component is great for presenting a concise list of options, particularly when showcasing time ranges due to its ample horizontal space. However, if there’s more than 5 choices, use the Select component instead.

Displaying a short list of time choices

The ChoiceList component is great for presenting a concise list of options, particularly when showcasing time ranges due to its ample horizontal space. However, if there’s more than 5 choices, use the [Select](/docs/api/checkout-ui-extensions/components/forms/select) component instead.

Displaying a short list of time choices

import {
reactExtension,
BlockStack,
ChoiceList,
Choice,
} from '@shopify/ui-extensions-react/checkout';

export default reactExtension(
'purchase.checkout.block.render',
() => <Extension />,
);

function Extension() {
return (
<ChoiceList
name="time"
value=""
onChange={(value) => {
console.log(
`onChange event with value: ${value}`,
);
}}
>
<BlockStack>
<Choice id="morning">
9:00 AM - 12:00 PM
</Choice>
<Choice id="afternoon">
12:00 PM - 3:00 PM
</Choice>
<Choice id="evening">
3:00 PM - 5:00 PM
</Choice>
</BlockStack>
</ChoiceList>
);
}
import {
extension,
BlockStack,
ChoiceList,
Choice,
} from '@shopify/ui-extensions/checkout';

export default extension(
'purchase.checkout.block.render',
(root) => {
const choiceList = root.createComponent(
ChoiceList,
{
name: 'time',
value: '',
onChange: (value) => {
console.log(
`onChange event with value: ${value}`,
);
},
},
[
root.createComponent(BlockStack, {}, [
root.createComponent(
Choice,
{id: 'morning'},
'9:00 AM - 12:00 PM',
),
root.createComponent(
Choice,
{id: 'afternoon'},
'12:00 PM - 3:00 PM',
),
root.createComponent(
Choice,
{id: 'evening'},
'3:00 PM - 5:00 PM',
),
]),
],
);

root.appendChild(choiceList);
},
);

  • Choose the right variant: Use the base variant for straightforward options and flexible layouts. Use the group variant when choices need stronger emphasis, full-row selection, or tighter alignment with checkout surfaces.
  • Keep labels concise: Write short, scannable labels so buyers can quickly compare their choices.
  • Use the details slot sparingly: Only show extra content in a choice's details when it's essential to the buyer's decision, such as a map for a selected pickup location.
  • Use Select for long lists: When you have many options, use the Select component to keep the interface compact.
  • Add a group label: Use the ChoiceList component's label to describe the set of choices, such as "Shipping speed" or "Contact method."

  • The base variant doesn't make the entire row clickable; use the group variant for full-row selection. Avoid nested interactive elements that harm accessibility.
  • The ChoiceList component captures plain selection values only. Complex nested content inside choices is for display purposes and isn't included in form data.


Was this page helpful?