---
title: Migrate to the Polaris choice list component
description: >-
  Learn how to migrate the ChoiceList component to Polaris web components in
  checkout and customer account UI extensions.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/choice-list
  md: >-
    https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/choice-list.md
---

# Migrate to the Polaris choice list component

The Polaris choice list component groups related [`<s-choice>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#choice) elements and renders them as radio buttons or checkboxes. It replaces the previous [`ChoiceList`](https://shopify.dev/docs/api/checkout-ui-extensions/2025-07/components/forms/choicelist) component and is available as [`<s-choice-list>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list) in API versions 2025-10 and newer.

***

## Updated properties

The following properties are different in the Polaris choice list component.

### variant

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. |

### value

The previous `ChoiceList` `value` prop maps to per-child [`selected`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#choice-propertydetail-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`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#properties-propertydetail-multiple) attribute to switch between single and multiple selection — the mode is no longer inferred from the value type.

You can also set [`values`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#properties-propertydetail-values) on `<s-choice-list>` as a shortcut for setting `selected` on the matching children.

## Migrating single selection

##### Latest (Preact)

```tsx
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)

```tsx
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`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#choice-propertydetail-defaultselected) on each `<s-choice>`.

## Migrating multiple selection

##### Latest (Preact)

```tsx
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)

```tsx
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>
  );
}
```

### on​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[]`.

***

## New properties

The Polaris choice list component introduces the following new properties:

| New prop | Type | Description |
| - | - | - |
| [`label`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#properties-propertydetail-label) | `string` | Sets the label text for the choice list. |
| [`labelAccessibilityVisibility`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#properties-propertydetail-labelaccessibilityvisibility) | `'visible'` \| `'exclusive'` | Controls the visibility of the label. Defaults to `'visible'`. |
| [`disabled`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#properties-propertydetail-disabled) | `boolean` | Disables all choices in the list. |
| [`error`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#properties-propertydetail-error) | `string` | Sets the error message to display. |
| [`id`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#properties-propertydetail-id) | `string` | Sets a unique identifier for the choice list. |
| [`multiple`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/choice-list#properties-propertydetail-multiple) | `boolean` | Renders the choices as checkboxes when `true`, or as radio buttons when `false`. |

***
