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 totargets
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, must be updated to
is now
[[extensions.targeting]]
and is expanded to include additional details. Most notably, you will need to provide amodule
, 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:
. 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 nestedextensions
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 nowshopify.extension.toml
Anchor to converting-the-extension-configuration-fileUpdate the configuration file
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"
).
Anchor to update-the-configuration-file-previous-shopify.ui.extension.tomlPrevious shopify.ui.extension.toml
Anchor to update-the-configuration-file-new-shopify.extension.tomlNew shopify.extension.toml
Previous shopify.ui.extension.toml
shopify.ui.extension.toml
Anchor to packagesUpdate the packages
We will be moving to a new set of packages for distributing UI extension APIs — and
will be replaced with
and
. 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 package with the
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.
Versions 2023.07.x
and later have a couple breaking changes compared to the 0.27.x
range of the 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.
Anchor to update-the-packages-previous-package.jsonPrevious package.json
Anchor to update-the-packages-new-package.jsonNew package.json
Previous package.json
package.json
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.
Anchor to update-the-extension-points-previous-code-(javascript)Previous code (JavaScript)
Anchor to update-the-extension-points-new-code-(javascript)New code (JavaScript)
Anchor to update-the-extension-points-previous-code-(react)Previous code (React)
Anchor to update-the-extension-points-new-code-(react)New code (React)
Previous index.ts
index.ts
Anchor to migrateMigrate your extensions
Deploy after applying the above changes to get your extensions migrated.
You will need to update your and
packages to version
3.48.0
or later in order to migrate to the package types.
Deploy
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 name | Extension target name |
---|---|
Checkout::Actions::RenderBefore | purchase.checkout.actions.render-before |
Checkout::CartLineDetails::RenderAfter | purchase.checkout.cart-line-item.render-after |
Checkout::CartLines::RenderAfter | purchase.checkout.cart-line-list.render-after |
Checkout::Contact::RenderAfter | purchase.checkout.contact.render-after |
Checkout::DeliveryAddress::RenderBefore | purchase.checkout.delivery-address.render-before |
Checkout::Dynamic::Render | purchase.checkout.block.render |
Checkout::GiftCard::Render | purchase.checkout.gift-card.render |
Checkout::OrderStatus::CartLineDetails::RenderAfter | customer-account.order-status.cart-line-item.render-after |
Checkout::OrderStatus::CartLines::RenderAfter | customer-account.order-status.cart-line-list.render-after |
Checkout::OrderStatus::Dynamic::Render | customer-account.order-status.block.render |
Checkout::PickupLocations::RenderAfter | purchase.checkout.pickup-location-list.render-after |
Checkout::PickupLocations::RenderBefore | purchase.checkout.pickup-location-list.render-before |
Checkout::PickupPoints::RenderAfter | purchase.checkout.pickup-point-list.render-after |
Checkout::PickupPoints::RenderBefore | purchase.checkout.pickup-point-list.render-before |
Checkout::Reductions::RenderAfter | purchase.checkout.reductions.render-after |
Checkout::Reductions::RenderBefore | purchase.checkout.reductions.render-before |
Checkout::ShippingMethodDetails::RenderAfter | purchase.checkout.shipping-option-item.render-after |
Checkout::ShippingMethodDetails::RenderExpanded | purchase.checkout.shipping-option-item.details.render |
Checkout::ShippingMethods::RenderAfter | purchase.checkout.shipping-option-list.render-after |
Checkout::ShippingMethods::RenderBefore | purchase.checkout.shipping-option-list.render-before |
Checkout::ThankYou::CartLineDetails::RenderAfter | purchase.thank-you.cart-line-item.render-after |
Checkout::ThankYou::CartLines::RenderAfter | purchase.thank-you.cart-line-list.render-after |
Checkout::ThankYou::CustomerInformation::RenderAfter | purchase.thank-you.customer-information.render-after |
Checkout::ThankYou::Dynamic::Render | purchase.thank-you.block.render |