---
title: Migrate ActionList from Polaris React
description: >-
  Replace the Polaris React ActionList component with a menu or a visible action
  composition using Polaris web components.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/action-list
  md: >-
    https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/action-list.md
api_name: app-home
---

# Migrate Action​List from Polaris React

Polaris web components don't have a like-for-like `ActionList` component. Choose the replacement based on the list's purpose:

| Existing `ActionList` | Polaris web components | Migration type |
| - | - | - |
| Contextual actions opened from a button or `Popover` | A trigger `s-button` and sibling `s-menu` | Compose |
| Actions that are always visible | An `s-stack` containing `s-button` or `s-link` elements | Compose |
| Selectable options | `s-choice-list` or `s-select` | Change pattern |
| Filterable resource actions | A resource index or another visible search-and-list pattern | Change pattern |

Don't move a persistent list into an overflow menu only because `s-menu` is the closest component by name. Preserve whether the actions are contextual, persistent, or selectable.

***

## Migrate a contextual Action​List

Polaris React commonly combines `Button`, `Popover`, and `ActionList`. In Polaris web components, the trigger references a sibling menu by ID, and the menu manages its overlay state.

## Migrate a contextual ActionList

##### Polaris web components

```tsx
function ProductActions({onDuplicate, onArchive, onDelete}) {
  return (
    <>
      <s-button commandFor="product-actions">More actions</s-button>
      <s-menu id="product-actions" accessibilityLabel="Product actions">
        <s-button icon="duplicate" onClick={onDuplicate}>
          Duplicate as draft
        </s-button>
        <s-button icon="archive" onClick={onArchive}>
          Archive product
        </s-button>
        <s-button icon="delete" tone="critical" onClick={onDelete}>
          Delete product
        </s-button>
      </s-menu>
    </>
  );
}
```

##### Polaris React

```tsx
import {useState} from 'react';
import {ActionList, Button, Popover} from '@shopify/polaris';
import {ArchiveIcon, DeleteIcon, DuplicateIcon} from '@shopify/polaris-icons';

export function ProductActions({onDuplicate, onArchive, onDelete}) {
  const [active, setActive] = useState(false);

  return (
    <Popover
      active={active}
      activator={
        <Button disclosure onClick={() => setActive((open) => !open)}>
          More actions
        </Button>
      }
      onClose={() => setActive(false)}
    >
      <ActionList
        actionRole="menuitem"
        items={[
          {
            content: 'Duplicate product',
            helpText: 'Creates a new draft product',
            icon: DuplicateIcon,
            onAction: onDuplicate,
          },
          {
            content: 'Archive product',
            icon: ArchiveIcon,
            onAction: onArchive,
          },
          {
            content: 'Delete product',
            destructive: true,
            icon: DeleteIcon,
            onAction: onDelete,
          },
        ]}
      />
    </Popover>
  );
}
```

The migrated example changes **Duplicate product** with the help text **Creates a new draft product** to the self-contained action label **Duplicate as draft**. `s-menu` items don't support secondary help text.

***

## Map Action​List properties

| Polaris React | Polaris web components | Migration type |
| - | - | - |
| `items` | Root-level `s-button` children of `s-menu` | Direct |
| `sections` | `s-section` children with `heading` and nested `s-button` elements | Compose |
| `actionRole` | Remove. `s-menu` supplies menu semantics and keyboard behavior. | Remove |
| `allowFiltering` and `filterLabel` | No menu equivalent. Use a visible search-and-list experience or a resource index. | Change pattern |
| `onActionAnyItem` | Call the shared callback from each item's `onClick` handler. | Compose |

An `s-menu` only accepts `s-button` and `s-section` children. Don't place `s-search-field` inside a menu to recreate `allowFiltering`.

***

## Map item properties

| Polaris React item property | Polaris web components | Migration type |
| - | - | - |
| `id` | `id` on `s-button` | Direct |
| `content` | Button text content | Direct |
| `accessibilityLabel` | `accessibilityLabel` | Direct |
| `url` | `href` | Direct |
| `external` or `target` | `target`, such as `target="_blank"` | Changed |
| `onAction` | `onClick` | Direct |
| `onMouseEnter` or `onTouchStart` | Keep a standard DOM event handler only when the behavior is still required. | Changed |
| `disabled` | `disabled` | Direct |
| `destructive` | `tone="critical"` | Direct |
| `icon` | A documented icon name string in `icon` | Changed |
| `helpText` | No menu-item equivalent. Rewrite the label or move essential explanation to visible page content. | Unsupported |
| `badge` | No menu-item badge. Include essential state in the label or show it outside the menu. | Unsupported |
| `image`, `prefix`, or `suffix` | No arbitrary menu-item content. Use a persistent composition when that content is essential. | Unsupported |
| `ellipsis` or `truncate` | Use a shorter action label. The menu owns item layout. | Changed |
| `active` | Don't use an action menu as a selection control. Use `s-choice-list` or `s-select`. | Change pattern |
| `variant` or `role` | Remove. The destination component owns its appearance and semantics. | Remove |

### Preserve help text intentionally

Don't silently discard `helpText`. Choose one of these migrations:

* Rewrite non-essential supporting text into a concise, self-contained action label.
* Keep the action visible and place essential explanation next to it using `s-text` or `s-paragraph`.
* Use a resource or settings pattern when the text describes resource state or a configurable choice.

Avoid moving essential instructions into a tooltip. Merchants must be able to understand the action without discovering hidden content.

### Migrate sections

Replace each section descriptor with an `s-section` inside `s-menu`. Move `sections[].title` to `heading` and render each item as a button. If a title is a custom React node, rewrite it as a concise string heading.

***

## Keep persistent actions visible

If the `ActionList` is always visible, replace it with explicit controls rather than introducing an overflow menu.

## Migrate a persistent ActionList

##### Polaris web components

```tsx
function ProductActions({onEdit, onDuplicate, onDelete}) {
  return (
    <s-stack gap="small" alignItems="stretch">
      <s-button variant="tertiary" inlineSize="fill" onClick={onEdit}>
        Edit details
      </s-button>
      <s-button variant="tertiary" inlineSize="fill" onClick={onDuplicate}>
        Duplicate product
      </s-button>
      <s-button variant="tertiary" inlineSize="fill" tone="critical" onClick={onDelete}>
        Delete product
      </s-button>
    </s-stack>
  );
}
```

##### Polaris React

```tsx
import {ActionList} from '@shopify/polaris';

export function ProductActions({onEdit, onDuplicate, onDelete}) {
  return (
    <ActionList
      items={[
        {content: 'Edit details', onAction: onEdit},
        {content: 'Duplicate product', onAction: onDuplicate},
        {content: 'Delete product', destructive: true, onAction: onDelete},
      ]}
    />
  );
}
```

***

## Test the migration

* Test opening, closing, and choosing menu items with a keyboard.
* Confirm that destructive and disabled actions retain their behavior.
* Test link actions with normal, modified, and middle clicks.
* Confirm that every removed `helpText`, badge, prefix, suffix, and active state has an intentional destination.
* Confirm that focus returns to the trigger after the menu closes.

***

## Remove Polaris React

After every `ActionList` call site is migrated:

1. Remove the `ActionList` import.
2. Remove `Popover` open state and close callbacks that only controlled the action list.
3. Remove imported Polaris React icons that were replaced by icon name strings.
4. Run interaction and accessibility tests for each destination pattern.

***

## Related guidance

* [Menu component](https://shopify.dev/docs/api/app-home/web-components/actions/menu)
* [Button component](https://shopify.dev/docs/api/app-home/web-components/actions/button)
* [Choice list component](https://shopify.dev/docs/api/app-home/web-components/forms/choice-list)
* [Resource index template](https://shopify.dev/docs/api/app-home/patterns/templates/resource-index)

***
