--- title: Upgrade to the latest API version and Polaris web components description: >- Learn how to upgrade your checkout UI extensions to use the latest API version and Polaris web components. source_url: html: >- https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components md: >- https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components.md --- # Upgrade to the latest API version and Polaris web components This guide explains the steps you need to take to migrate your customer account UI extensions to the latest API version, including the removal of checkout metafield write types. **Info:** If you're upgrading from a version earlier than `2025-10`, you'll need to adopt Polaris web components. Versions `2025-10` and later use web components by default. []() *** ## Step 1: Update API version Update the API version to the latest version in `shopify.extension.toml` (for example, `2026-04`). ## shopify.extension.toml ```toml api_version = "2026-04" [[extensions]] name = "your-extension" handle = "your-extension" type = "ui_extension" # Contents of your existing file... ``` []() *** ## Step 2: Migrate to order metafields In `2026-04`, checkout metafields in the `metafields` API is replaced by order metafields in the [`appMetafields` API](https://shopify.dev/docs/api/customer-account-ui-extensions/2026-04/target-apis/order-apis/metafields-api). To set an order metafield during checkout, you must have an extension using a [pre-purchase Checkout UI extension target](https://shopify.dev/docs/api/checkout-ui-extensions/latest/targets#checkout) and use the `applyMetafieldChange` Metafield API to write a cart metafield that has the [`cart_to_order_copyable` capability](https://shopify.dev/docs/apps/build/metafields/use-metafield-capabilities#cart-to-order-copyable). See [this guide](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components#step-2-migrate-to-cart-metafields) for detailed instructions. ### Request metafields in your extension TOML Request metafields that your extension needs access to in your extension configuration using `[[extensions.metafields]]`. See [configuration](https://shopify.dev/docs/apps/build/app-extensions/configure-app-extensions#customer-account-ui-extensions) for more details. ## shopify.extension.toml ```toml [[extensions.metafields]] namespace = "my-namespace" key = "gift-requested" ``` ### Update API calls Instead of reading metafields using the `shopify.metafields` API or `useMetafield`, use `shopify.appMetafields` to read order metafield values. #### Before migration: using metafields API (now removed) ## package.json ## tsx ```tsx import "@shopify/ui-extensions/preact"; import { render } from "preact"; import { useMetafield } from "@shopify/ui-extensions/customer-account/preact"; export default function extension() { render(, document.body); } function Extension() { const giftRequested = useMetafield({ namespace: "my-namespace", key: "gift-requested", }); return ( Gift requested: {giftRequested?.value === "true" ? "Yes" : "No"} ); } ``` #### After migration: using appMetafields for order metafields ## package.json ## tsx ```tsx import "@shopify/ui-extensions/preact"; import { render } from "preact"; export default async () => { render(, document.body); }; function Extension() { const giftRequested = shopify.appMetafields.value.find( (appMetafield) => appMetafield.target.type === "order" && appMetafield.metafield.namespace === "my-namespace" && appMetafield.metafield.key === "gift-requested", ); return ( Gift requested: {giftRequested?.metafield?.value === "true" ? "Yes" : "No"} ); } ``` []() *** ## Step 3: Adopt web components and Preact The following sections apply if you're upgrading from a version earlier than `2025-10`. If you're already using web components and Preact, you don't need to make any changes. ### Adjust package dependencies For API versions `2025-10` and later, Shopify recommends Preact for UI extensions. Update the dependencies in your `package.json` file and re-install. #### New dependencies with Preact ## package.json ## New dependencies with Preact ```json { "dependencies": { "preact": "^10.10.x", "@preact/signals": "^2.3.x", "@shopify/ui-extensions": "2026.4.x" } } ``` #### Previous dependencies with React ## package.json ## Previous dependencies with React ```json { "dependencies": { "react": "^18.0.0", "@shopify/ui-extensions": "2025.4.x", "@shopify/ui-extensions-react": "2025.4.x", "react-reconciler": "0.29.0" }, "devDependencies": { "@types/react": "^18.0.0" } } ``` #### Previous dependencies with JavaScript ## package.json ## Previous dependencies with JavaScript ```json { "dependencies": { "@shopify/ui-extensions": "2025.4.x" } } ``` ### Type​Script configuration Get full IntelliSense and auto-complete support by adding a config file for your extension at `extensions/{extension-name}/tsconfig.json`. You don't need to change your app's root `tsconfig.json` file. #### New tsconfig.json ## tsconfig.json ## New tsconfig.json ```json { "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "preact", "target": "ES2020", "checkJs": true, "allowJs": true, "moduleResolution": "node", "esModuleInterop": true }, "include": ["./src", "./shopify.d.ts"] } ``` #### Old tsconfig.json ## tsconfig.json ## Old tsconfig.json ```json { "compilerOptions": { "jsx": "react-jsx" }, "include": ["./src"] } ``` ### Upgrade the Shopify CLI The new CLI adds support for building with web components. The `shopify app dev` command runs your app and also generates a `shopify.d.ts` file in your extension directory, adding support for the new global `shopify` object. ## Support new global shopify object ## CLI ```bash # Upgrade to latest version of the CLI npm install -g @shopify/cli # Run the app to generate the type definition file shopify app dev ``` ### Optional ESLint configuration If your app is using ESLint, update your configuration to include the new global `shopify` object. ## .eslintrc.cjs ```js module.exports = { globals: { shopify: 'readonly', }, }; ``` ### Migrate API calls Instead of accessing APIs from a callback parameter, access them from the global `shopify` object. Here's an example of migrating the Cart Line Target API call. #### New API calls in Preact ## Preact ## New API calls in Preact ```tsx import '@shopify/ui-extensions/preact'; import {render} from 'preact'; export default function extension() { render(, document.body); } function Extension() { return ( Line item title: {shopify.target.value.merchandise.title} ); } ``` #### Previous API calls in React ## React ## Previous API calls in React ```tsx import { reactExtension, Text, useCartLineTarget, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.order-status.cart-line-item.render-after', () => , ); function Extension() { const { merchandise: {title}, } = useCartLineTarget(); return Line item title: {title}; } ``` #### Previous API calls in JavaScript ## JavaScript ## Previous API calls in JavaScript ```tsx import {extension} from '@shopify/ui-extensions/customer-account'; export default extension( 'customer-account.order-status.cart-line-item.render-after', (root, {target}) => { const text = root.createText(`Line item title: ${target.current.title}`); root.appendChild(text); target.subscribe((updatedTarget) => { text.updateText(`Line item title: ${updatedTarget.title}`); }); }, ); ``` []() ### Migrate to web components Web components are exposed as custom HTML elements. Update your React or JavaScript components to custom elements. #### New components in Preact ## Preact ## New components in Preact ```tsx /* eslint-disable react/self-closing-comp */ import '@shopify/ui-extensions/preact'; import {render} from 'preact'; export default function extension() { render(, document.body); } function Extension() { return ( Save ); } ``` #### Previous components in React ## React ## Previous components in React ```tsx import { reactExtension, InlineStack, TextField, Button, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { return ( ); } ``` #### Previous components in JavaScript ## JavaScript ## Previous components in JavaScript ```ts import { extension, InlineStack, TextField, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, _api) => { root.replaceChildren( root.createComponent(InlineStack, {}, [ root.createComponent(TextField, { label: 'Gift message', }), root.createComponent(Button, {}, 'Save'), ]), ); }, ); ``` []() ### Mapping legacy components to web components | **Legacy component** | **Migration guide** | | - | - | | `Avatar` | [Migrate Avatar](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components/avatar) | | `Badge` | [Migrate Badge](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/badge) | | `Banner` | [Migrate Banner](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/banner) | | `BlockLayout` | [Migrate BlockLayout](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/block-layout) | | `BlockSpacer` | [Migrate BlockSpacer](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/block-spacer) | | `BlockStack` | [Migrate BlockStack](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/block-stack) | | `Button` | [Migrate Button](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/button) | | `Card` | [Migrate Card](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components/card) | | `Checkbox` | [Migrate Checkbox](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/checkbox) | | `Choice` | [Migrate Choice](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/choice) | | `ChoiceList` | [Migrate ChoiceList](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/choice-list) | | `ClipboardItem` | [Migrate ClipboardItem](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/clipboard-item) | | `ConsentCheckbox` | [Migrate ConsentCheckbox](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/consent-checkbox) | | `ConsentPhoneField` | [Migrate ConsentPhoneField](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/consent-phone-field) | | `CustomerAccountAction` | [Migrate CustomerAccountAction](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components/customer-account-action) | | `DateField` | [Migrate DateField](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/date-field) | | `DatePicker` | [Migrate DatePicker](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/date-picker) | | `Disclosure` | [Migrate Disclosure](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/disclosure) | | `Divider` | [Migrate Divider](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/divider) | | `DropZone` | [Migrate DropZone](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/drop-zone) | | `Form` | [Migrate Form](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/form) | | `Grid` | [Migrate Grid](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/grid) | | `GridItem` | [Migrate GridItem](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/grid-item) | | `Heading` | [Migrate Heading](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/heading) | | `HeadingGroup` | [Migrate HeadingGroup](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/heading-group) | | `Icon` | [Migrate Icon](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/icon) | | `Image` | [Migrate Image](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/image) | | `ImageGroup` | [Migrate ImageGroup](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components/image-group) | | `InlineLayout` | [Migrate InlineLayout](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/inline-layout) | | `InlineSpacer` | [Migrate InlineSpacer](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/inline-spacer) | | `InlineStack` | [Migrate InlineStack](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/inline-stack) | | `Link` | [Migrate Link](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/link) | | `List` | [Migrate List](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/list) | | `ListItem` | [Migrate List](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/list) | | `Map` | [Migrate Map](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/map) | | `MapMarker` | [Migrate MapMarker](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/map-marker) | | `MapPopover` | [Migrate MapPopover](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/map-popover) | | `Menu` | [Migrate Menu](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components/menu) | | `Modal` | [Migrate Modal](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/modal) | | `Page` | [Migrate Page](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components/page) | | `PaymentIcon` | [Migrate PaymentIcon](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/payment-icon) | | `PhoneField` | [Migrate PhoneField](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/phone-field) | | `Popover` | [Migrate Popover](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/popover) | | `Pressable` | [Migrate Pressable](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/pressable) | | `ProductThumbnail` | [Migrate ProductThumbnail](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/product-thumbnail) | | `QRCode` | [Migrate QRCode](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/qr-code) | | `ResourceItem` | [Migrate ResourceItem](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components/resource-item) | | `ScrollView` | [Migrate ScrollView](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/scroll-view) | | `Select` | [Migrate Select](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/select) | | `Sheet` | [Migrate Sheet](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/sheet) | | `SkeletonImage` | [Migrate SkeletonImage](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/skeleton-image) | | `SkeletonText` | [Migrate SkeletonText](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/skeleton-text) | | `SkeletonTextBlock` | [Migrate SkeletonTextBlock](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/skeleton-text-block) | | `Spinner` | [Migrate Spinner](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/spinner) | | `Stepper` | [Migrate Stepper](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/stepper) | | `Style` helper | [Migrate Style helper](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/style-helper) | | `Switch` | [Migrate Switch](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/switch) | | `Tag` | [Migrate Tag](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/tag) | | `Text` | [Migrate Text](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/text) | | `TextBlock` | [Migrate TextBlock](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/text-block) | | `TextField` | [Migrate TextField](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/text-field) | | `ToggleButton` | [Migrate ToggleButton](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/toggle-button) | | `ToggleButtonGroup` | [Migrate ToggleButtonGroup](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/toggle-button-group) | | `Tooltip` | [Migrate Tooltip](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/tooltip) | | `View` | [Migrate View](https://shopify.dev/docs/apps/build/checkout/migrate-to-web-components/view) | ***