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

# Migrate to the Polaris text field components

The previous [`TextField`](https://shopify.dev/docs/api/checkout-ui-extensions/2025-07/ui-components/forms/textfield) component has been split into dedicated components based on the `type` prop. Each type now has its own Polaris web component, available in API versions 2025-10 and newer.

***

## Component mapping by type

The `type` prop you previously set on `TextField` determines which new component to use:

| Previous `type` | New component | Documentation |
| - | - | - |
| `'text'` (default) | [`<s-text-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-field) | [Text field](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-field) |
| `'email'` | [`<s-email-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/email-field) | [Email field](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/email-field) |
| `'number'` | [`<s-number-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/number-field) | [Number field](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/number-field) |
| `'telephone'` | [`<s-phone-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/phone-field) | [Phone field](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/phone-field). See also the [phone field migration guide](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/phone-field) for property-level changes. |
| No previous equivalent | [`<s-url-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/url-field) | [URL field](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/url-field). New component — previously, URL inputs used `<TextField type="text">`. Switch to `<s-url-field>` for built-in URL validation and keyboard. |
| `multiline` prop | [`<s-text-area>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-area) | [Text area](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-area) |

## Migrating TextField type='email' to s-email-field

##### Latest (Preact)

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

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

function Extension() {
  return (
    <s-email-field
      label="Email address"
    />
  );
}
```

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

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

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

function Extension() {
  return (
    <TextField
      label="Email address"
      type="email"
    />
  );
}
```

## Migrating TextField type='number' to s-number-field

##### Latest (Preact)

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

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

function Extension() {
  return (
    <s-number-field
      label="Quantity"
    />
  );
}
```

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

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

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

function Extension() {
  return (
    <TextField
      label="Quantity"
      type="number"
    />
  );
}
```

## Migrating TextField type='telephone' to s-phone-field

##### Latest (Preact)

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

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

function Extension() {
  return (
    <s-phone-field
      label="Phone number"
    />
  );
}
```

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

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

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

function Extension() {
  return (
    <TextField
      label="Phone number"
      type="telephone"
    />
  );
}
```

## Migrating multiline TextField to s-text-area

##### Latest (Preact)

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

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

function Extension() {
  return (
    <s-text-area
      label="Order notes"
      rows={3}
    />
  );
}
```

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

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

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

function Extension() {
  return (
    <TextField
      label="Order notes"
      multiline={3}
    />
  );
}
```

***

## Updated properties

The following table summarizes which new components support the `icon` prop and the `accessory` slot:

| Component | `icon` prop | `accessory` slot |
| - | - | - |
| [`<s-text-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-field) | Yes | Yes |
| [`<s-email-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/email-field) | No | Yes |
| [`<s-number-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/number-field) | Yes | Yes |
| [`<s-phone-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/phone-field) | No | Yes |
| [`<s-url-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/url-field) | No | Yes |
| [`<s-text-area>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-area) | No | No |

### readonly

The previous `TextField` `readonly` prop is now called `readOnly` (camelCase) on all field components.

### accessory

The previous `TextField` `accessory` prop has been replaced with the `accessory` slot on [`<s-text-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-field#slots-propertydetail-accessory), [`<s-email-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/email-field#slots-propertydetail-accessory), [`<s-number-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/number-field#slots-propertydetail-accessory), [`<s-phone-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/phone-field#slots-propertydetail-accessory), and [`<s-url-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/url-field#slots-propertydetail-accessory). Place an element with `slot="accessory"` as a child of the field. The `accessory` slot isn't available on [`<s-text-area>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-area) — to position supplementary content next to a text area, use layout components.

## Migrating accessory from prop to slot

##### Latest (Preact)

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

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

function Extension() {
  return (
    <s-text-field label="Search products">
      <s-icon slot="accessory" type="info" />
    </s-text-field>
  );
}
```

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

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

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

function Extension() {
  return (
    <TextField
      label="Search products"
      accessory={<Icon source="info" />}
    />
  );
}
```

### icon

The `icon` prop is supported only on [`<s-text-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-field#properties-propertydetail-icon) and [`<s-number-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/number-field#properties-propertydetail-icon). On those components, update icon names to their Polaris web component equivalents — they use the same icon names as the Polaris [icon](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/media-and-visuals/icon) component. The `icon` prop isn't available on [`<s-email-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/email-field), [`<s-phone-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/phone-field), or [`<s-url-field>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/url-field). For a trailing icon (the previous `icon={{source: '...', position: 'end'}}`), use the `accessory` slot — it only renders at the end of the field. A leading-position icon (the previous default) has no direct equivalent on those components; place an icon next to the field using layout components, or omit it.

**Note:**

This table lists only icon values that need more than a camelCase-to-kebab-case rename. If an icon isn't listed here, then convert its previous camelCase name to kebab-case. For example, `arrowLeft` becomes `arrow-left`.

| Previous icon | New icon |
| - | - |
| `'checkmark'` | `'check'` |
| `'close'` | `'x'` |
| `'critical'` | `'alert-circle'` |
| `'error'` | `'x-circle'` |
| `'errorFill'` | `'x-circle-filled'` |
| `'gift'` | `'gift-card'` |
| `'giftFill'` | `'gift-card'` |
| `'hamburger'` | `'menu'` |
| `'hollowCircle'` | `'circle'` |
| `'horizontalDots'` | `'menu-horizontal'` |
| `'infoFill'` | `'info-filled'` |
| `'list'` | `'list-bulleted'` |
| `'magnify'` | `'search'` |
| `'marker'` | `'location'` |
| `'orderBox'` | `'order'` |
| `'pen'` | `'edit'` |
| `'question'` | `'question-circle'` |
| `'questionFill'` | `'question-circle-filled'` |
| `'starFill'` | `'star-filled'` |
| `'success'` | `'check-circle'` |
| `'verticalDots'` | `'menu-vertical'` |
| `'warning'` | `'alert-triangle'` |
| `'warningFill'` | `'alert-triangle-filled'` |

## Migrating icon values

##### Latest (Preact)

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

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

function Extension() {
  return (
    <s-text-field
      label="Search products"
      icon="search"
    />
  );
}
```

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

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

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

function Extension() {
  return (
    <TextField
      label="Search products"
      icon="magnify"
    />
  );
}
```

## Migrating a trailing icon to the accessory slot

##### Latest (Preact)

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

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

function Extension() {
  return (
    <s-email-field label="Email address">
      <s-icon slot="accessory" type="info" />
    </s-email-field>
  );
}
```

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

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

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

function Extension() {
  return (
    <TextField
      label="Email address"
      type="email"
      icon={{source: 'info', position: 'end'}}
    />
  );
}
```

***

## Removed properties

The following properties aren't supported on any of the new field components:

* `type` — no longer needed. Use the dedicated component for your input type instead.
* `multiline` — no longer supported. Use [`<s-text-area>`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/forms/text-area) instead.
* `accessibilityDescription` — no longer supported. Use the `label` prop to provide context.
* `controlledValue` — no longer supported. Use the standard value management pattern.

***

## New properties

The new field components introduce the following properties:

| New prop | Type | Description |
| - | - | - |
| `labelAccessibilityVisibility` | `'visible'` \| `'exclusive'` | Controls whether the label is visually displayed or only available to screen readers. Default is `'visible'`. |
| `minLength` | `number` | Specifies the minimum number of characters required. |
| `defaultValue` | `string` | Initial value for uncontrolled usage. |

***
