--- title: ChoiceList description: >- The choice list component presents multiple options for single or multiple selections. api_version: 2025-07 api_name: customer-account-ui-extensions source_url: html: >- https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/forms/choicelist md: >- https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/forms/choicelist.md --- Migrate to Polaris Version 2025-07 is the last API version to support React-based UI components. Later versions use [web components](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/polaris-web-components), native UI elements with built-in accessibility, better performance, and consistent styling with [Shopify's design system](https://shopify.dev/docs/apps/design). Check out the [migration guide](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components) to upgrade your extension. # ChoiceList The choice list component presents multiple options for single or multiple selections. Use it when customers need to choose from a defined set of options. The component supports both single selection (radio button behavior) and multiple selection (checkbox behavior) modes. It includes configurable labels, help text, and validation. For compact dropdown selection with four or more options, use [Select](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/forms/select). ### Support Targets (25) ### Supported targets * Customer​Account::Kitchen​Sink * [customer-account.​footer.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/footer#footer-render-after-) * [customer-account.​order-index.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-index#order-index-targets) * [customer-account.​order-index.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-index#order-index-block-) * [customer-account.​order-status.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#order-status-announcement-) * [customer-account.​order-status.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#order-status-block-) * [customer-account.​order-status.​cart-line-item.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#cart-line-item-render-after-) * [customer-account.​order-status.​cart-line-list.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#cart-line-list-render-after-) * [customer-account.​order-status.​customer-information.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#customer-information-render-after-) * [customer-account.​order-status.​fulfillment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/fulfillment-status#fulfillment-status-targets) * [customer-account.​order-status.​payment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/payments-and-returns#payments-and-returns-targets) * [customer-account.​order-status.​return-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/payments-and-returns#return-details-render-after-) * [customer-account.​order-status.​unfulfilled-items.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/fulfillment-status#unfulfilled-items-render-after-) * [customer-account.​order.​action.​menu-item.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-actions#order-action-menu-item-) * [customer-account.​order.​action.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-actions#order-action-) * [customer-account.​order.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/full-page#order-specific-full-page-) * [customer-account.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/full-page#customer-account-full-page-) * [customer-account.​profile.​addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#profile-page-default-targets-) * [customer-account.​profile.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#announcement-) * [customer-account.​profile.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#profile-block-) * [customer-account.​profile.​company-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#profile-page-b2b-targets-) * [customer-account.​profile.​company-location-addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-addresses-render-after-) * [customer-account.​profile.​company-location-payment.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-payment-render-after-) * [customer-account.​profile.​company-location-staff.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-staff-render-after-) * customer-account.​profile.​payment.​render-after #### Use cases * **Pickup locations**: Let customers select a preferred pickup point from a list. * **Preference selection**: Offer single-select options like delivery speed or contact method. * **Multi-select**: Allow customers to choose multiple items, such as add-ons or interests. * **Compact layouts**: Display up to five options without the overhead of a dropdown. *** ## Properties Configure the following properties on the ChoiceList component. * **name** **string** **required** A unique identifier for the field in the closest `Form` component. * **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](https://reactjs.org/docs/forms.html#controlled-components), so you must store this value in state and reflect it back in the `value` prop. * **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**. * **variant** **'base' | 'group'** **Default: 'base'** Toggle between `base` and `group` look. Check the [best practices](#best-practices) to learn more about the variants. *** ## Examples ### Pick from a set of options Use choice list to present a set of options that customers can select from. This example shows a basic single-select choice list with radio buttons. ## Pick from a set of options ![A choice list with radio button options](https://shopify.dev/assets/assets/images/templated-apis-screenshots/checkout-ui-extensions/2025-07/choicelist-default-DyFQgTYb.png) ## Pick from a set of options ##### React ```tsx import { reactExtension, BlockStack, Choice, ChoiceList, Icon, InlineStack, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.page.render', () => , ); function Extension() { return ( { console.log( `onChange event with value: ${value}`, ); }} > } id="ship" > Ship } id="ship-to-pickup-point" > Ship to pickup point } id="pick-up" > Pick up in store { console.log( `onChange event with value: ${value}`, ); }} > Save this information for next time Email me with news and offers Text me with news and offers ); } ``` ##### JS ```js import { extension, InlineStack, ChoiceList, Choice, BlockStack, Icon, } from '@shopify/ui-extensions/customer-account'; export default extension('customer-account.page.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); }); ``` ### Build a custom survey using the base variant The base variant's flexibility allows for the creation of Likert scales using the choice list component. By using layout components, you can easily structure rows and columns for this purpose. ## Build a custom survey using the base variant ![A Likert scale survey built with the base variant of ChoiceList](https://shopify.dev/assets/assets/images/templated-apis-screenshots/checkout-ui-extensions/2025-07/choicelist-survey-D7EHKVm-.png) ## Build a custom survey using the base variant ##### React ```tsx import { reactExtension, Choice, ChoiceList, Grid, TextBlock, View, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { return ( Strongly disagree Disagree Neutral Agree Strongly agree { console.log( `onChange event with value: ${value}`, ); }} > I recommend Plant to others. { console.log( `onChange event with value: ${value}`, ); }} > I have had a positive experience purchasing from Plant. { console.log( `onChange event with value: ${value}`, ); }} > I would purchase from Plant again. ); } ``` ##### JavaScript ```js 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', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Strongly disagree', ), ), root.createComponent( View, { padding: ['tight', 'extraTight'], blockAlignment: 'center', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Disagree', ), ), root.createComponent( View, { padding: ['tight', 'extraTight'], blockAlignment: 'center', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Neutral', ), ), root.createComponent( View, { padding: ['tight', 'extraTight'], blockAlignment: 'center', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Agree', ), ), root.createComponent( View, { padding: ['tight', 'extraTight'], blockAlignment: 'center', accessibilityVisibility: 'hidden', }, root.createComponent( TextBlock, {inlineAlignment: 'center'}, 'Strongly agree', ), ), // Then create the ChoiceList for 'question1' root.createComponent( ChoiceList, { name: 'question1', value: '', onChange: (value) => { console.log( `onChange event with value: ${value}`, ); }, }, [ root.createComponent( View, { background: 'subdued', padding: 'base', blockAlignment: 'center', }, root.createComponent( TextBlock, {}, 'I recommend Plant to others.', ), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-1', accessibilityLabel: 'Strongly disagree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-2', accessibilityLabel: 'Disagree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-3', accessibilityLabel: 'Neutral', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-4', accessibilityLabel: 'Agree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question1-5', accessibilityLabel: 'Strongly agree', }), ), ], ), // Then create the ChoiceList for 'question2' root.createComponent( ChoiceList, { name: 'question2', value: '', onChange: (value) => { console.log( `onChange event with value: ${value}`, ); }, }, [ root.createComponent( View, { padding: 'base', blockAlignment: 'center', }, root.createComponent( TextBlock, {}, 'I have had a positive experience purchasing from Plant.', ), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-1', accessibilityLabel: 'Strongly disagree', }), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-2', accessibilityLabel: 'Disagree', }), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-3', accessibilityLabel: 'Neutral', }), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-4', accessibilityLabel: 'Agree', }), ), root.createComponent( View, { blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question2-5', accessibilityLabel: 'Strongly agree', }), ), ], ), // Then create the ChoiceList for 'question3' root.createComponent( ChoiceList, { name: 'question3', value: '', onChange: (value) => { console.log( `onChange event with value: ${value}`, ); }, }, [ root.createComponent( View, { background: 'subdued', padding: 'base', blockAlignment: 'center', }, root.createComponent( TextBlock, {}, 'I would purchase from Plant again.', ), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-1', accessibilityLabel: 'Strongly disagree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-2', accessibilityLabel: 'Disagree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-3', accessibilityLabel: 'Neutral', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-4', accessibilityLabel: 'Agree', }), ), root.createComponent( View, { background: 'subdued', blockAlignment: 'center', inlineAlignment: 'center', }, root.createComponent(Choice, { id: 'question3-5', accessibilityLabel: 'Strongly agree', }), ), ], ), ], ); root.appendChild(grid); }, ); ``` ### Collect additional information The choice list's group variant, combined with the details property, allows for the conditional display of information when needed. ## Collect additional information ![A choice list with conditional detail fields shown for the selected option](https://shopify.dev/assets/assets/images/templated-apis-screenshots/checkout-ui-extensions/2025-07/choicelist-details-DyHZjta9.png) ## Collect additional information ##### React ```tsx import { reactExtension, BlockStack, Choice, ChoiceList, DatePicker, TextBlock, TextField, View, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { return ( { console.log( `onChange event with value: ${value}`, ); }} > Choose a delivery date The more detailed the delivery instructions are, the best we can make the delivery experience for you. } > Use white glove delivery service ); } ``` ##### JavaScript ```js 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); }, ); ``` ### Display a short list of time choices The choice list component is great for presenting a concise list of options, particularly when showcasing time ranges due to its ample horizontal space. However, if there are more than 5 choices, use the [select](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/forms/select) component instead. ## Display a short list of time choices ![A choice list displaying time slot options in a compact layout](https://shopify.dev/assets/assets/images/templated-apis-screenshots/checkout-ui-extensions/2025-07/choicelist-time-picking-CBomUSgK.png) ## Display a short list of time choices ##### React ```tsx import { reactExtension, BlockStack, ChoiceList, Choice, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { return ( { console.log( `onChange event with value: ${value}`, ); }} > 9:00 AM - 12:00 PM 12:00 PM - 3:00 PM 3:00 PM - 5:00 PM ); } ``` ##### JavaScript ```js 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); }, ); ``` *** ## Best practices * **Keep labels concise**: Write short, scannable labels so customers can quickly compare their choices. * **Add a group label**: Use the `label` property to describe the purpose of the choice list, such as "Shipping speed" or "Contact method." * **Use select for long lists**: When you have four or more options and screen space is limited, use [Select](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/ui-components/forms/select) to keep the interface compact and scrollable. *** ## Limitations * Component is either single or multiple selection for all choices. ***