Migrate to the Polaris text field components
The previous 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.
Anchor to Component mapping by typeComponent 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> | Text field |
'email' | <s-email-field> | Email field |
'number' | <s-number-field> | Number field |
'telephone' | <s-phone-field> | Phone field. See also the phone field migration guide for property-level changes. |
| No previous equivalent | <s-url-field> | 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> | Text area |
Migrating TextField type='email' to s-email-field
Latest (Preact)
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)
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)
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)
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)
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)
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)
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)
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}
/>
);
}Anchor to Updated propertiesUpdated properties
The following table summarizes which new components support the icon prop and the accessory slot:
| Component | icon prop | accessory slot |
|---|---|---|
<s-text-field> | Yes | Yes |
<s-email-field> | No | Yes |
<s-number-field> | Yes | Yes |
<s-phone-field> | No | Yes |
<s-url-field> | No | Yes |
<s-text-area> | No | No |
Anchor to readonlyreadonly
The previous TextField readonly prop is now called readOnly (camelCase) on all field components.
Anchor to accessoryaccessory
The previous TextField accessory prop has been replaced with the accessory slot on <s-text-field>, <s-email-field>, <s-number-field>, <s-phone-field>, and <s-url-field>. Place an element with slot="accessory" as a child of the field. The accessory slot isn't available on <s-text-area> — to position supplementary content next to a text area, use layout components.
Migrating accessory from prop to slot
Latest (Preact)
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)
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" />}
/>
);
}Anchor to iconicon
The icon prop is supported only on <s-text-field> and <s-number-field>. On those components, update icon names to their Polaris web component equivalents — they use the same icon names as the Polaris icon component. The icon prop isn't available on <s-email-field>, <s-phone-field>, or <s-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.
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.
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)
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)
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)
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)
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'}}
/>
);
}Anchor to Removed propertiesRemoved 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>instead.accessibilityDescription— no longer supported. Use thelabelprop to provide context.controlledValue— no longer supported. Use the standard value management pattern.
Anchor to New propertiesNew 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. |