Migrate Text Field from Polaris React
Polaris React TextField covered several input types and multiline values. Replace each call site with the most specific Polaris web component field so browsers, password managers, mobile keyboards, validation, and form submission understand the value.
If the app renders a controlled replacement field through React, upgrade to React 19 first. React 18 doesn't provide the custom-element property and event behavior these examples rely on. If you can't upgrade yet, leave the controlled Polaris React field in place during this migration slice.
Anchor to Choose the destination fieldChoose the destination field
| Existing value | Polaris web components |
|---|---|
| General single-line text | s-text-field |
| Email address | s-email-field |
| Number | s-number-field |
| Password or secret | s-password-field |
| URL | s-url-field |
| Search query | s-search-field |
| Multiline text | s-text-area |
Don't route every call site to s-text-field. For example, changing a numeric field into a general text field loses numeric input behavior and makes range validation harder to maintain.
Anchor to Migrate a field and validationMigrate a field and validation
Migrating a validated text field
Polaris web components
<s-text-field
label="SKU"
value="TSHIRT-001"
autocomplete="off"
error="SKU 'TSHIRT-001' already exists. SKUs must be unique across all products."
></s-text-field>Polaris React
import {TextField} from '@shopify/polaris';
export function ProductSku({
sku = 'TSHIRT-001',
error = "SKU 'TSHIRT-001' already exists. SKUs must be unique across all products.",
onChange,
}) {
return (
<TextField
label="SKU"
value={sku}
error={error}
autoComplete="off"
onChange={onChange}
/>
);
}Preview
| Polaris React | Polaris web components | Migration notes |
|---|---|---|
label | label | Keep a concise, persistent label. |
labelHidden | labelAccessibilityVisibility="exclusive" | Don't remove the accessible name. |
helpText | details | Keep format or usage guidance with the field. |
error | error | Pass a specific string that explains how to recover. |
requiredIndicator | required | The property doesn't create an error automatically. Validate and set error when needed. |
value | value | Pass the controlled string value. |
onChange(value, id) | onInput(event) or onChange(event) | Use onInput for immediate state updates and read event.currentTarget.value. Use onChange when commit-style timing fits the workflow. |
autoComplete | autocomplete | Keep a valid autocomplete token for the field's purpose. |
placeholder | placeholder | Use examples or format hints, not the only label. |
disabled and readOnly | disabled and readOnly | Preserve whether the value is unavailable or view-only. |
maxLength | maxLength | Keep client and server limits aligned. |
multiline | s-text-area and rows | Choose a text area and an appropriate initial height. |
type="number", min, max, and step | s-number-field, min, max, and step | Keep the value numeric in domain and validation code. |
Review prefix, suffix, connected controls, clear buttons, and vertical content individually. Don't rebuild unsupported adornments around every field. Keep units in a clear label or adjacent semantic text, and put separate actions outside the field when they remain understandable and keyboard reachable.
Anchor to Preserve validation and submissionPreserve validation and submission
Use one source of truth for the displayed value, client validation, and submission payload. Server validation remains authoritative. After a failed submission, restore the attempted values and show each field error next to its control, plus page-level feedback when the whole submission failed.
Set a stable name when using native form submission. Verify empty values, whitespace normalization, locale-specific number input, and secret redaction rather than assuming the old TextField adapters still run.
Anchor to Test the migrationTest the migration
- Enter, clear, paste, autofill, and submit every field type.
- Verify immediate and commit-style event timing doesn't duplicate requests.
- Trigger required, format, range, uniqueness, and server validation errors.
- Test browser autofill and the intended mobile keyboard for email, number, URL, and search fields.
- Reload editing forms and verify controlled values don't reset unexpectedly.
- Confirm labels, details, errors, prefixes, and units are announced in the intended order.
Anchor to Remove Polaris ReactRemove Polaris React
After every call site is migrated, remove TextField, value-only callback adapters, and adornment wrappers that no longer have a caller. Remove @shopify/polaris only after no other route in scope imports it.