Skip to main content

API versioning and unified UI extensions

As of Summer Editions 2023 (July 26), we have introduced some important changes to checkout UI extensions:

  • The introduction of API versioning and the associated API versioning strategy
  • Changes to the configuration toml file that match the format for other app extensions
  • extension points have been renamed to targets

For more details on the above, please visit our post on the ui-extensions public repository


Anchor to what-changed-in-the-toml-fileWhat changed in the toml file

The main changes you will need to make will be to your configuration file (shopify.ui.extension.toml). We changed a few of the fields you currently use to configure a UI extension:

  • type, which currently is set to checkout_ui_extension, must be updated to ui_extension
  • extension_points is now [[extensions.targeting]] and is expanded to include additional details. Most notably, you will need to provide a module, which is a reference to the file in your project that implements the extension. metafields that you will query must also now be specified per-extension point
  • a new mandatory field: api_version. This field must be a Shopify API version, in the same format you would use for Shopify's REST and GraphQL APIs. This version will control what extension points, components, and APIs are available to your extension, and will come with the same 1 year (minimum) guarantee as our other APIs. The first public API version for checkout UI extensions was 2023-07
  • handle, which should be set in the nested extensions level of your configuration file. This is a unique identifier for your extension, and will be used to reference it from other extensions. We recommend using dash casing for the handle (for example, my-extension for an extension named "My extension")
  • shopify.ui.extension.toml is now shopify.extension.toml

First, rename your shopify.ui.extension.toml file to shopify.extension.toml.

Next, update the extension configuration file to the new format. To make it easier for the CLI to detect which extensions are being migrated to the new format, you should have the directory name of the extension match the new handle field you provide. We recommend making both the directory name and handle fields be the handle-cased version of your extension name (for example, my-extension for an extension with name = "My extension").

Previous shopify.ui.extension.toml

shopify.ui.extension.toml

type = "checkout_ui_extension"
name = "My Extension"

extension_points = ['Checkout::Dynamic::Render']

[[metafields]]
namespace = "my_namespace"
key = "my_key"

[settings]
[[settings.fields]]
key = "banner_title"
type = "single_line_text_field"
name = "Banner title"
description = "Enter a title for the banner"

Anchor to packagesUpdate the packages

We will be moving to a new set of packages for distributing UI extension APIs — @shopify/checkout-ui-extensions and @shopify/checkout-ui-extensions-react will be replaced with @shopify/ui-extensions/checkout and @shopify/ui-extensions-react/checkout. These new packages will allow you to implement extensions for multiple surfaces without requiring multiple dependencies. You'll need to update any import for the existing packages with the new package.

In your package.json, replace any @shopify/checkout-ui-extensions package with the @shopify/ui-extensions equivalent.

You will notice that the UI extension packages have a new versioning system. In the new versions, the "major" version number is the API version year (e.g., 2023), the "minor" version number is the API version month (e.g., 10 for 2023.10), and the "patch" version number is reserved by Shopify for making bugfixes on the contents of the package (e.g. .1 for 2023.10.1). You will need to match the version of the package you install to the API version your extension targets, so that you get access to the types and runtime utilities associated with that API version. We recommend using a version that locks in the major and minor version numbers, and allows the patch version to be updated, like the 2023.10.x version range shown above.

Caution

Versions 2023.07.x and later have a couple breaking changes compared to the 0.27.x range of the @shopify/checkout-ui-extensions(-react) packages. If you want to upgrade to the new API versioning system, but continue to use the APIs you were using before without any changes, we also provide a 2023.4.x version range that contains the same APIs as the 0.27.x range of the old packages.

Previous package.json

package.json

{
"dependencies": {
"@shopify/checkout-ui-extensions": "^0.27.0",
"@shopify/checkout-ui-extensions-react": "^0.27.0"
}
}

Anchor to extension-pointsUpdate the extension points

Finally, the new format has a slightly different system for registering your extension target code. The file you list as the module for a given extension target must export your extension target code as the default export from the module.

Previous index.ts

index.ts

import {
extend,
Banner,
} from '@shopify/checkout-ui-extensions';

extend(
'Checkout::Dynamic::Render',
(root, {extensionPoint, i18n}) => {
root.appendChild(
root.createComponent(
Banner,
{title: 'My extension'},
i18n.translate('welcome', {
extensionPoint,
}),
),
);
},
);

Anchor to migrateMigrate your extensions

Deploy after applying the above changes to get your extensions migrated.

Note

You will need to update your @shopify/app and @shopify/cli packages to version 3.48.0 or later in order to migrate to the ui_extensions package types.

Deploy

❯ yarn deploy
yarn run v1.22.19
$ shopify app deploy

╭─ info ───────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ Extension migrations can't be undone. │
│ │
│ Your "my-extension" configuration has been updated. Migrating gives you access to new │
│ features and won't impact the end user experience. All previous extension versions will reflect │
│ this change. │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯

? Migrate "my-extension"?

> (y) Yes, confirm migration from "checkout_ui_extension"
(n) No, cancel

Anchor to extension-targets-listReference: extension point to extension target

Extension targets are more flexible and powerful than extension points and they allow to link UI extensions with functions.

Extension point nameExtension target name
Checkout::Actions::RenderBeforepurchase.checkout.actions.render-before
Checkout::CartLineDetails::RenderAfterpurchase.checkout.cart-line-item.render-after
Checkout::CartLines::RenderAfterpurchase.checkout.cart-line-list.render-after
Checkout::Contact::RenderAfterpurchase.checkout.contact.render-after
Checkout::DeliveryAddress::RenderBeforepurchase.checkout.delivery-address.render-before
Checkout::Dynamic::Renderpurchase.checkout.block.render
Checkout::GiftCard::Renderpurchase.checkout.gift-card.render
Checkout::OrderStatus::CartLineDetails::RenderAftercustomer-account.order-status.cart-line-item.render-after
Checkout::OrderStatus::CartLines::RenderAftercustomer-account.order-status.cart-line-list.render-after
Checkout::OrderStatus::Dynamic::Rendercustomer-account.order-status.block.render
Checkout::PickupLocations::RenderAfterpurchase.checkout.pickup-location-list.render-after
Checkout::PickupLocations::RenderBeforepurchase.checkout.pickup-location-list.render-before
Checkout::PickupPoints::RenderAfterpurchase.checkout.pickup-point-list.render-after
Checkout::PickupPoints::RenderBeforepurchase.checkout.pickup-point-list.render-before
Checkout::Reductions::RenderAfterpurchase.checkout.reductions.render-after
Checkout::Reductions::RenderBeforepurchase.checkout.reductions.render-before
Checkout::ShippingMethodDetails::RenderAfterpurchase.checkout.shipping-option-item.render-after
Checkout::ShippingMethodDetails::RenderExpandedpurchase.checkout.shipping-option-item.details.render
Checkout::ShippingMethods::RenderAfterpurchase.checkout.shipping-option-list.render-after
Checkout::ShippingMethods::RenderBeforepurchase.checkout.shipping-option-list.render-before
Checkout::ThankYou::CartLineDetails::RenderAfterpurchase.thank-you.cart-line-item.render-after
Checkout::ThankYou::CartLines::RenderAfterpurchase.thank-you.cart-line-list.render-after
Checkout::ThankYou::CustomerInformation::RenderAfterpurchase.thank-you.customer-information.render-after
Checkout::ThankYou::Dynamic::Renderpurchase.thank-you.block.render