---
title: Migrate to the Polaris button component
description: >-
  Learn how to migrate the Button 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/button
  md: >-
    https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/button.md
---

# Migrate to the Polaris button component

The Polaris button component triggers actions and navigation. It replaces the previous [`Button`](https://shopify.dev/docs/api/checkout-ui-extensions/2025-07/ui-components/actions/button) component and is available as [`<s-button>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button) in API versions 2025-10 and newer.

***

## Updated properties

The following properties are different in the Polaris button component.

### on​Press

The previous `Button` `onPress` prop is now called [`onClick`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#events-propertydetail-click).

### to

The previous `Button` `to` prop is now called [`href`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-href).

### appearance

The previous `Button` `appearance` prop is now called [`tone`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-tone).

| Previous value | New value | Migration notes |
| - | - | - |
| Default (no value) | `'auto'` | `'auto'` is the new default. |
| `'critical'` | `'critical'` | No change needed. |
| `'monochrome'` | Removed | `monochrome` is no longer available. `'neutral'` is the closest alternative, but the behavior isn't identical. |

### kind

The previous `Button` `kind` prop is now called [`variant`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-variant).

| Previous value | New value | Migration notes |
| - | - | - |
| Default (primary) | `'auto'` | The default changed from `'primary'` to `'auto'`. |
| `'primary'` | `'primary'` | No change needed. |
| `'secondary'` | `'secondary'` | No change needed. |
| `'plain'` | Removed | Use [`<s-link>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/link) instead. |

## Migrating kind to variant

##### Latest (Preact)

```tsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';

export default function extension() {
  render(<Extension />, document.body);
}

function Extension() {
  return (
    <s-button variant="secondary">
      Cancel
    </s-button>
  );
}
```

##### Pre-Polaris (2025-07)

```tsx
import {
  reactExtension,
  Button,
} from '@shopify/ui-extensions-react/checkout';

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

function Extension() {
  return (
    <Button kind="secondary">
      Cancel
    </Button>
  );
}
```

## Migrating kind='plain' to s-link

##### Latest (Preact)

```tsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';

export default function extension() {
  render(<Extension />, document.body);
}

function Extension() {
  return (
    <s-link href="/details">
      View details
    </s-link>
  );
}
```

##### Pre-Polaris (2025-07)

```tsx
import {
  reactExtension,
  Button,
} from '@shopify/ui-extensions-react/checkout';

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

function Extension() {
  return (
    <Button kind="plain" to="/details">
      View details
    </Button>
  );
}
```

### submit and accessibility​Role="submit"

The previous `Button` `submit` prop and `accessibilityRole="submit"` have been replaced with [`type="submit"`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-type).

| Previous pattern | New pattern | Migration notes |
| - | - | - |
| `submit={true}` | `type="submit"` | Use `type` prop. |
| `accessibilityRole="submit"` | `type="submit"` | Use `type` prop. |

***

## Removed properties

### toggles, activate​Action, and activate​Target

The previous `Button` `toggles`, `activateAction`, and `activateTarget` props have been replaced with [`command`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-command) and [`commandFor`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-commandfor).

| Previous pattern | New pattern | Migration notes |
| - | - | - |
| `toggles="modal-id"` | `command="--toggle"` + `commandFor="modal-id"` | Toggle behavior for modals, sheets, etc. |
| `activateAction="copy"` + `activateTarget="element-id"` | `command="--copy"` + `commandFor="element-id"` | Copy behavior now uses the command pattern. |

## Migrating activateAction to command

##### Latest (Preact)

```tsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';

export default function extension() {
  render(<Extension />, document.body);
}

function Extension() {
  return (
    <>
      <s-button command="--copy" commandFor="promo-code">
        Copy promo code
      </s-button>
      <s-clipboard-item id="promo-code" text="SAVE25"></s-clipboard-item>
    </>
  );
}
```

##### Pre-Polaris (2025-07)

```tsx
import {
  reactExtension,
  Button,
  ClipboardItem,
} from '@shopify/ui-extensions-react/checkout';

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

function Extension() {
  return (
    <>
      <Button activateAction="copy" activateTarget="promo-code">
        Copy promo code
      </Button>
      <ClipboardItem id="promo-code" text="SAVE25" />
    </>
  );
}
```

### Combining toggle and copy

The previous `Button` accepted both `toggles` (to show an overlay like a tooltip) and `activateAction` (to copy a value) on the same element. With the new command pattern, [`command`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-command) accepts a single action. To copy a value and surface a tooltip from the same button, use `command="--copy"` for the copy action and [`interestFor`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-interestfor) to show a sibling [`<s-tooltip>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/overlays/tooltip) on hover and focus.

## Migrating combined toggles and activateAction

##### Latest (Preact)

```tsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';

export default function extension() {
  render(<Extension />, document.body);
}

function Extension() {
  return (
    <>
      <s-button
        command="--copy"
        commandFor="promo-code"
        interestFor="copy-tooltip"
      >
        Copy promo code
      </s-button>
      <s-tooltip id="copy-tooltip">Copies SAVE25 to the clipboard</s-tooltip>
      <s-clipboard-item id="promo-code" text="SAVE25"></s-clipboard-item>
    </>
  );
}
```

##### Pre-Polaris (2025-07)

```tsx
import {
  reactExtension,
  Button,
  ClipboardItem,
  Tooltip,
} from '@shopify/ui-extensions-react/checkout';

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

function Extension() {
  return (
    <>
      <Button
        toggles="copy-tooltip"
        activateAction="copy"
        activateTarget="promo-code"
        overlay={
          <Tooltip id="copy-tooltip">
            Copies SAVE25 to the clipboard
          </Tooltip>
        }
      >
        Copy promo code
      </Button>
      <ClipboardItem id="promo-code" text="SAVE25" />
    </>
  );
}
```

### loading​Label

The Polaris button component no longer supports `loadingLabel`. Loading state accessibility is handled automatically.

### inline​Alignment

The Polaris button component no longer supports `inlineAlignment`. The previous `Button` filled its container by default, and `inlineAlignment` aligned the button's content within that full-width control. The Polaris button defaults to intrinsic width ([`inlineSize="auto"`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-inlinesize)), so to preserve the previous behavior, set `inlineSize="fill"` and wrap the button's children in [`<s-stack>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/layout-and-structure/stack) using [`justifyContent`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/layout-and-structure/stack#properties-propertydetail-justifycontent) to align the content. There isn't a dedicated content-alignment prop on `<s-button>`, so the nested stack is the recommended pattern.

**\`'fill'\` on \`\<s-button>\` vs. \`\<s-box>\`:**

`<s-button>` keeps the `'fill'` keyword for [`inlineSize`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-inlinesize). This differs from `<s-box>`, where `'fill'` is removed in favor of `'100%'`. Each component's accepted values are documented on its own reference page.

## Migrating inlineAlignment to a content stack

##### Latest (Preact)

```tsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';

export default function extension() {
  render(<Extension />, document.body);
}

function Extension() {
  return (
    <s-button inlineSize="fill">
      <s-stack direction="inline" justifyContent="end" minInlineSize="100%">
        Pay now
      </s-stack>
    </s-button>
  );
}
```

##### Pre-Polaris (2025-07)

```tsx
import {
  reactExtension,
  Button,
  Text,
} from '@shopify/ui-extensions-react/checkout';

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

function Extension() {
  return (
    <Button inlineAlignment="end">
      <Text>Pay now</Text>
    </Button>
  );
}
```

### overlay

The Polaris button component no longer supports `overlay`. Render the overlay as a sibling element with an `id` and wire the trigger to it. The migration pattern depends on what kind of overlay you're showing:

* For modals, sheets, and popovers (click-activated overlays): use [`command`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-command) and [`commandFor`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-commandfor) on the trigger.
* For tooltips (hover/focus-activated overlays): use [`interestFor`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-interestfor) on the trigger pointing to a sibling `<s-tooltip id="...">`. See the [tooltip migration guide](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/tooltip) for details.

The example below shows the modal case.

## Migrating overlay to command

##### Latest (Preact)

```tsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';

export default function extension() {
  render(<Extension />, document.body);
}

function Extension() {
  return (
    <>
      <s-button command="--show" commandFor="details-modal">
        More info
      </s-button>
      <s-modal id="details-modal" heading="Details">
        <s-paragraph>Delivery in 2 to 4 business days.</s-paragraph>
      </s-modal>
    </>
  );
}
```

##### Pre-Polaris (2025-07)

```tsx
import {
  reactExtension,
  Button,
  Modal,
  Text,
} from '@shopify/ui-extensions-react/checkout';

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

function Extension() {
  return (
    <Button
      overlay={
        <Modal id="details-modal" title="Details">
          <Text>Delivery in 2 to 4 business days.</Text>
        </Modal>
      }
    >
      More info
    </Button>
  );
}
```

***

## New properties

The Polaris button component introduces the following new properties:

| New prop | Type | Description |
| - | - | - |
| [`command`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-command) | `'--auto'` \| `'--toggle'` \| `'--copy'` \| `'--show'` \| `'--hide'` | Sets the action to run when the button is activated. |
| [`commandFor`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-commandfor) | `string` | Sets the ID of the target component for the command. |
| [`inlineSize`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-inlinesize) | `'auto'` \| `'fill'` \| `'fit-content'` | Controls the button's inline size. Defaults to `'auto'`. |
| [`target`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-target) | `'auto'` \| `'_blank'` | Controls where a linked URL opens when `href` is used. |
| [`interestFor`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-interestfor) | `string` | Sets the ID of the component that should respond to hover and focus. |

### inline​Size

The previous `Button` component filled the available inline space by default. The Polaris button component defaults to `'auto'` sizing. Set [`inlineSize='fill'`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button#properties-propertydetail-inlinesize) to match the previous behavior.

| Previous value | New value | Migration notes |
| - | - | - |
| Default (fill) | `'auto'` | Set `inlineSize='fill'` to preserve the previous behavior. |

***
