Publish Checkout Kit Web to Shopify's CDN alongside npm. A major-versioned
ES module loader at /checkout-kit/v<major>/web-components.js registers
components on demand via loadComponents(['shopify-checkout']); component
names are the custom element tags they register. A maintainer-only
/v<major>/unstable/ channel exists for exercising prereleases.
Builds: `build:npm` writes dist/ (root plus the shopify-checkout entry,
sharing one chunk) and `build:cdn` writes dist-cdn/ (loader plus a
self-contained hashed component chunk). Packing builds only npm output, so
CDN assets never enter the package. Both distributions register through
the component's register.ts, which leaves an existing <shopify-checkout>
in place, so loading npm and CDN together does not throw.
Loader: validates every name before fetching, shares in-flight loads,
remembers loaded components, and retries failed imports through a unique
cache-busting URL per sequence (browsers remember a failed import per URL
for the life of the page). A build plugin injects the hashed chunk URL.
Exports `version` and `supportedComponents`.
Release workflow:
- Content-hashed chunks upload before the loader that references them.
The stable URL updates only for a non-prerelease version, not flagged as
a GitHub prerelease, published to npm `latest`; everything else goes to
the unstable channel for its major.
- A token-only pre-flight confirms the deploy identity holds the bucket
permissions the upload needs, before anything irreversible happens and
without leaving credentials on disk for package code. Full
authentication happens only after npm publication; `npm publish` runs
with --ignore-scripts so the verified dist/ is what ships.
- The deploy identity and bucket are npm-web environment secrets rather
than committed values: identifiers, not credentials, but masked in logs
and readable only by jobs declaring the environment. The workflow fails
early, without printing values, if any is missing.
- Re-running a release (or a failed manual run) redeploys the CDN assets
for an already-published version, which doubles as rollback. A fresh
manual dispatch of an already-published version is refused, since main
may no longer match the published tarball.
- The CDN route applies one cache policy to every /checkout-kit/ path, so
the workflow sets no per-object Cache-Control and the docs describe the
real ~30 minute propagation window and a bad-deploy runbook.
Known limitation: no supported path yet for patching an older major after
a new major ships; tracked separately.
What changes are you making?
Add on-demand CDN loading to Checkout Kit Web, using the component structure and npm subpath introduced in #940. One package and version produce separate outputs:
build:npmwritesdist/, andbuild:cdnwritesdist-cdn/. Packing builds only npm output; CDN assets stay out of the npm package.The loader imports only requested components. The URL is evergreen within a Checkout Kit major version, independent of the underlying protocol version; components share that library version. Hashed implementation chunks are deployment details. The loader also exports
versionandsupportedComponents, validates requests before importing, shares concurrent loads, and retries transient import failures.The npm registration entry remains:
Both distributions use the component's
register.ts, which registers throughShopifyCheckout.register()and leaves an existing<shopify-checkout>in place, so loading npm and CDN together does not throw. The npm root registers nothing (#940); the distribution tests cover the npm component entry and the npm root alongside the CDN loader, in both orders. No separatecdn-components/source directory is needed.Publishing: the release workflow builds and verifies both outputs, checks deploy permissions before npm publication, and uploads hashed CDN chunks before the loader. Stable non-prerelease releases published to npm
latestupdate the major URL; other releases use the maintainer-onlyv<major>/unstable/channel. Re-running the original release can redeploy or roll back its CDN assets. Deployment, caching, and rollback details are inplatforms/web/CDN-PUBLISHING.mdandplatforms/web/RELEASING.md.Known limitation: maintenance releases for older majors are not supported yet; this needs addressing before a new major ships.
Open question: the public filename remains
web-components.js. This is a callable loader, unlike the Storefront side-effect bundle; the filename should be settled before first publication.How to test
Validation passed in the public checkout: 355 unit tests, 16 Chromium tests, 11 built-package tests, lint/typechecks, publint, the sample build, the packed-file snapshot comparison, and actionlint. Built-package tests cover consumer bundling and TypeScript resolution, isolated stable/unstable CDN layouts, and both npm/CDN loading orders.
After merge, a dry run from
maincan exercise deploy permissions without publishing. The first real prerelease deployment uses the unstable channel; the stable URL becomes available with4.0.0.