Alokai

1.1

absolute imports become mandatory, page-view metering ships turned on, and @alokai/cli 2.0.0 changes how stores are recognised

Showing every integration. Set your stack in Preferences and this page hides what isn't yours.

Minorlatest 1.1.0 · 26 Jun 2025Node 20.* || >=22.14.0

Plan a real afternoon for this release, because every project has work to do. storefront-middleware becomes a composite TypeScript project, and all four apps switch from relative to absolute imports. That's an eleven-part migration you apply by hand, with no automatic path. @alokai/cli goes to 2.0.0 and treats a store as a template unless its alokai.config.json entry has a deployment field, so a project that changes nothing can find its stores silently reclassified as templates. Upgrading @alokai/connect, @vue-storefront/next, or @vue-storefront/nuxt turns on Alokai page-view metering in production: a script that sends a trace on every navigation, and two new middleware endpoints. You turn it off with an environment variable.

Highlights

Your apps must move to absolute imports, and storefront-middleware becomes a composite TypeScript project

Action neededStorefront@alokai/cli@vue-storefront/eslint-config
Why:

Absolute imports inside storefront-middleware don't resolve from the apps unless the apps reference the middleware as a TypeScript project. That's why the switch to absolute imports and the composite middleware are one change.

storefront-middleware declares compilerOptions.composite: true. storefront-unified-nextjs and storefront-unified-nuxt consume it as a TypeScript Project Reference, so absolute imports inside it resolve from both apps.

@vue-storefront/eslint-config 5.1.0 adds a multistore rule group that rewrites relative imports to aliased ones. @alokai/cli adds store prepare, which generates the paths and include arrays in per-store tsconfig.json files. Store tsconfig files inherit shared configuration from the root config instead of each store carrying a private copy.

For you:

The upgrade doesn't apply any of this for you. The tsconfigs, eslint configs, turbo.json, and app package.json files are yours, so you make every edit by hand, in order, and then run yarn lint:fix to rewrite the imports across every app and store. Skip it and tsc stops resolving imports inside storefront-middleware from the apps, and your Playwright integration tasks run before the middleware build they now depend on.

Don't stop halfway, or your build fails altogether. Making the middleware composite breaks the type check that next build runs, and the step's last part is what fixes it.

See the step in the upgrade guide →

Page-view metering is now on by default in production

Action neededStorefront@alokai/connect@vue-storefront/next@vue-storefront/nuxt@alokai/instrumentation@alokai/instrumentation-next-component@alokai/instrumentation-nuxt2-module@alokai/instrumentation-nuxt3-module
Why:

Alokai measures fair-use accounting in page views, so the core packages now count them without any configuration.

Four new packages measure page views for fair-use accounting, and the three core packages wire them in with no configuration. In the middleware, createServer in @alokai/connect registers POST /alokai-trace, a Prometheus page-view counter. It also registers GET /alokai-metrics, which serves that counter plus the prom-client default process metrics - heap, CPU, and event loop.

In Next.js, AlokaiProvider in @vue-storefront/next renders an inline beforeInteractive next/script that POSTs to <origin>/api/alokai-trace on every history navigation. In Nuxt, the @vue-storefront/nuxt module installs a plugin that does the same from router.beforeEach. Both scripts switch themselves off in development. The middleware endpoints don't - createServer registers them in every mode.

For you:

On Alokai Cloud, you've already agreed to page-view metering, and /alokai-metrics is blocked at the edge. If you host the middleware yourself, it exposes /alokai-metrics on whatever hostname your middleware answers, in development too. If you host a storefront yourself, a production build starts sending traces. To turn it off, set the opt-out variable to true for each app you host yourself: ALOKAI_IS_SELF_HOSTED for the middleware, NEXT_PUBLIC_ALOKAI_IS_SELF_HOSTED for Next.js, and NUXT_PUBLIC_ALOKAI_IS_SELF_HOSTED for Nuxt.

See the step in the upgrade guide →

@alokai/cli 2.0.0 treats a store without a deployment field as a template

Action neededCLI & tooling@alokai/cli
Why:

You couldn't parametrise a template store in alokai.config.json, because giving a store any config at all made it a deployable store.

A store is a template unless its alokai.config.json entry has a deployment field. Before, a store was a template only when its entry had no config at all. A template store can now be parametrised in alokai.config.json.

For you:

If a store you build, run, or deploy has no deployment field in its entry, the CLI now skips it as a template. Nothing errors - store build, store dev, and store deploy just stop composing it. Check every entry in alokai.config.json before you run anything, and add a deployment field to each store that isn't a template.

See the step in the upgrade guide →

@vsf-enterprise/middleware-headers 3.0.0 changes your CDN cache key and stops ignoring per-method headers

Action neededAlokai Connect@vsf-enterprise/middleware-headers
Why:

Under multistore and integration routing, the content the middleware returns depends on x-alokai-middleware-config-id and x-alokai-locale, but the Vary header didn't list them.

The extension appends x-alokai-middleware-config-id and x-alokai-locale to the Vary header of every response it touches, merged with any Vary you set yourself. The top-level cacheControl option no longer suppresses the per-method headers section. A Cache-Control you set for a specific method now wins over the general one instead of being a no-op.

For you:

Your CDN cache key widens, so expect a lower hit rate until the new key warms up. There's nothing to change in your config for this.

If you set a per-method Cache-Control alongside a top-level cacheControl, that header was silently doing nothing and now takes effect. That changes what your CDN caches, from a config you never touched. Drop the per-method header to keep what your CDN did before, or leave it to accept the new behavior.

See the step in the upgrade guide →

All changes by area

Every change in 1.1 has one entry here, grouped by area. The highlights, from above and from the patch sections, are here too, marked with a star. Open an area to see its changes, and open a change to read why it changed and what changed. The upgrade guide from 1.0.2 to 1.1.0 collects the migration steps for the whole line.

Alokai ConnectAction needed4 changes

changed @vsf-enterprise/middleware-headers 3.0.0 changes your CDN cache key and stops ignoring per-method headers highlight Action needed

Your CDN cache key widens, so expect a lower hit rate until it warms up. A per-method Cache-Control you set alongside a top-level cacheControl was silently doing nothing and now takes effect - drop it to keep what your CDN did before, or leave it to accept the new behavior.

step →
What changed ▸
Why

Under multistore and integration routing, the content the middleware returns depends on x-alokai-middleware-config-id and x-alokai-locale, but the Vary header didn't list them.

Changed

The extension appends x-alokai-middleware-config-id and x-alokai-locale to Vary on every response it touches, merged with any Vary you set yourself. The top-level cacheControl option no longer suppresses the per-method headers section, so a Cache-Control set for a specific method now wins over the general one.

@vsf-enterprise/middleware-headers

changed context.getApiClient is typed as returning a promise Action needed

If you call context.getApiClient in a custom middleware method or extension, add await to every call. An unawaited call that used to typecheck now fails tsc.

step →
What changed ▸
Why

Federated code could call context.getApiClient without await and still typecheck. The call always returned a promise at runtime, so that code was already broken.

Changed

context.getApiClient in @alokai/connect's MiddlewareContext is typed as returning Promise<ApiClient>.

@alokai/connect

changed The config switcher falls back to the default config id

A request that used to be rejected for a missing header now resolves against the default config.

What changed ▸
Changed

@alokai/connect/config-switcher accepts a request with no config header at all and uses the default config id. Before, it required the header.

@alokai/connect

removed dotenv is gone from the Connect logger

You don't need to add it. Your root package.json has carried "dotenv": "16.4.7" in dependencies all along, so the import 'dotenv/config' in your middleware keeps resolving through the workspace root.

What changed ▸
Changed

@alokai/connect/logger no longer depends on dotenv, so you can use the logger in React Native projects. A project generated at 1.1.0 declares dotenv 16.4.7 directly in apps/storefront-middleware/package.json instead.

@alokai/connect
StorefrontAction needed9 changes

changed Your apps must move to absolute imports, and storefront-middleware becomes a composite TypeScript project highlight Action needed

The upgrade doesn't apply any of this for you - you edit the tsconfigs, eslint configs, turbo.json, and app package.json files by hand, in order. Don't stop halfway, or your build fails: making the middleware composite breaks the type check that next build runs.

step →
What changed ▸
Why

Absolute imports inside storefront-middleware don't resolve from the apps unless the apps reference the middleware as a TypeScript project. That's why the switch to absolute imports and the composite middleware are one change.

Changed

storefront-middleware declares compilerOptions.composite: true, and both storefront apps consume it as a TypeScript Project Reference. @vue-storefront/eslint-config 5.1.0 adds a multistore rule group that rewrites relative imports to aliased ones. @alokai/cli adds store prepare to generate the paths and include arrays in per-store tsconfig.json files, and store tsconfig files inherit shared configuration from the root config.

@alokai/cli@vue-storefront/eslint-config

added Page-view metering is now on by default in production highlight Action needed

On Alokai Cloud, you've already agreed to page-view metering, and /alokai-metrics is blocked at the edge. A middleware you host yourself exposes /alokai-metrics on your own hostname, and a storefront you host yourself sends traces from a production build, until you set the opt-out variable to true for each app you host yourself: ALOKAI_IS_SELF_HOSTED for the middleware, NEXT_PUBLIC_ALOKAI_IS_SELF_HOSTED for Next.js, and NUXT_PUBLIC_ALOKAI_IS_SELF_HOSTED for Nuxt.

step →
What changed ▸
Why

Alokai measures fair-use accounting in page views, so the core packages now count them without any configuration.

Changed

createServer in @alokai/connect registers POST /alokai-trace and GET /alokai-metrics on your middleware. AlokaiProvider in @vue-storefront/next renders an inline beforeInteractive next/script that POSTs to <origin>/api/alokai-trace on every history navigation. The @vue-storefront/nuxt module installs a plugin that does the same from router.beforeEach. Both scripts switch themselves off in development, but the middleware endpoints don't.

@alokai/connect@vue-storefront/next@vue-storefront/nuxt@alokai/instrumentation@alokai/instrumentation-next-component@alokai/instrumentation-nuxt2-module@alokai/instrumentation-nuxt3-module

fixed Nuxt hydration warnings on the size and colour chips and the checkout layout are fixed

These files belong to your project, so your copies keep the old markup until you port the change.

What changed ▸
Changed

The size filter chips in components/CategoryFilters/FilterSize.vue and the product page's size and colour chips in components/ProductAttributes/ProductAttributes.vue get real id/for pairs. layouts/checkout.vue wraps the checkout layout's loader and slot in <ClientOnly>. Together, they stop the hydration warnings in storefront-unified-nuxt.

removed The no-JavaScript price fallback is dropped from the Nuxt product cards

Both files are yours, so your copies keep the <noscript> markup until you port the change.

What changed ▸
Changed

components/ui/ProductCard/ProductCard.vue and components/ui/PurchaseCard/PurchaseCard.vue no longer carry the <noscript> DecoratedPrice fallbacks. A client with JavaScript disabled no longer sees prices. SkeletonGeneric gains min-h-10 to hold the space instead.

changed The Nuxt lazy-load types are renamed per composable

The types live in your own project, so the old names keep working until you rename them yourself.

What changed ▸
Changed

LazyLoadFn and LazyLoadFnReturn in composables/useLazyProduct/types.ts become ProductLazyLoadFn and ProductLazyLoadFnReturn. The pair in composables/useLazySearchProducts/types.ts becomes SearchProductsLazyLoadFn and SearchProductsLazyLoadFnReturn.

added The Alokai version is readable from the Nuxt app config and the composed .env

If you upgraded rather than generated, the upgrade never touches that version field. The value in your composed .env stays at the version that generated your project - a project created at 1.0.0 and upgraded to 1.1.0 reports 1.0.0. Nothing in the storefront reads the variable, so there's nothing to repair. It's worth knowing because the value is public, and because later releases resolve other things from that same field.

What changed ▸
Changed

The @vue-storefront/nuxt module injects NUXT_PUBLIC_ALOKAI_VERSION into Nuxt's appConfig. @alokai/cli writes the variable into the composed .env, from the version field of .alokai/package.json or the root package.json. It's NEXT_PUBLIC_ALOKAI_VERSION for storefront-unified-nextjs and NUXT_PUBLIC_ALOKAI_VERSION for storefront-unified-nuxt.

@vue-storefront/nuxt@alokai/cli

changed The generated app manifests gain a typecheck script and pin their tooling Action needed

Your own build still runs only next build until you change it, and you must change it - next build can't type-check a composite project. The shared eslint pin is also why the composite-project step offers a root resolutions entry as its fallback.

step →
What changed ▸
Why

next build can't type-check a composite project. The type check has to move to a compiler that honours project references, and the manifest has to declare it as a script.

Changed

apps/storefront-unified-nextjs/package.json gains a typecheck script, and build becomes yarn typecheck && next build. eslint is pinned from ^9.22.0 to 9.23.0, and prettier 3.3.2 is added as a devDependency. The same eslint pin lands in apps/storefront-middleware/package.json, apps/playwright/package.json, and apps/storefront-unified-nuxt/package.json.

Two other pins move with it, and they're yours to take or leave: express from 4.20.0 to 4.21.2 in the middleware, and happy-dom from 14.12.3 to 15.10.2 in the Nuxt app.

fixed The register-b2b module picks up a userAlreadyExists message and new test ids Action needed

If you installed the register-b2b module, port all of it to your copies. Until you do, they still carry the old test ids, and the module's Playwright suite keeps failing on locators that no longer match.

step →
What changed ▸
Why

The Nuxt register form had no message for an existing user. The module's files are copies in your project, so a fix to the module's source doesn't reach them.

Changed

The Nuxt register form in apps/storefront-unified-nuxt/components/RegisterForm/RegisterForm.vue gains a userAlreadyExists error message. data-testid="success-modal" moves onto the modal element itself. The message textarea's test id becomes message-input, and the module's Playwright suite is fixed to match.

fixed The re-order module binds its defineProps result Action needed

If you installed the re-order module, the file is a copy in your project, so the one-line fix is yours to apply.

step →
What changed ▸
Why

The component references props.product.id but never binds the defineProps result.

Changed

The re-order module's apps/storefront-unified-nuxt/components/CartPageProductCard/CartPageProductCard.vue assigns its defineProps result to props.

CLI & toolingAction needed13 changes

changed @alokai/cli 2.0.0 treats a store without a deployment field as a template highlight Action needed

If a store you build, run, or deploy has no deployment field in its entry, the CLI now skips it as a template. Nothing errors - store build, store dev, and store deploy just stop composing it.

step →
What changed ▸
Why

You couldn't parametrise a template store in alokai.config.json, because giving a store any config at all made it a deployable store.

Changed

A store is a template unless its alokai.config.json entry has a deployment field. Before, a store was a template only when its entry had no config at all.

@alokai/cli

added store lint is a new command, and the root lint scripts cover stores

You get the command with the CLI. The root scripts are yours, so they keep skipping stores until you extend them - the composite-project step does that as one of its parts.

What changed ▸
Changed

store lint is a new @alokai/cli command. A generated project's root lint and lint:fix scripts now lint the stores directory as well as the base apps.

@alokai/cli

added store rename changes a store id

You no longer edit alokai.config.json and the store directory by hand to rename a store.

What changed ▸
Changed

alokai-cli store rename --store-id sapcc-b2c --new-store-id sapcc-my-brand renames a store.

@alokai/cli

added build, dev, start and test take a --turbo-option passthrough flag

You can pass a Turbo option on the command line. Before, the only way to set it was to edit turbo.json.

What changed ▸
Changed

build, dev, start, and test in @alokai/cli accept a --turbo-option flag. The flag passes custom options through to the underlying Turbo task.

@alokai/cli

added alokai.config.json honours an ignorePaths field

You can declare the paths you want the CLI to leave out of a store in config, instead of working around them.

What changed ▸
Changed

alokai.config.json now honours an ignorePaths field.

@alokai/cli

added integration generate can use local boilerplate code and lints what it writes

A generated integration arrives formatted to your own lint rules. You can try boilerplate changes without publishing them first.

What changed ▸
Changed

integration generate in @alokai/cli takes a flag to use local boilerplate code instead of a published version. It lints the files it generates with the project's lint:fix script.

@alokai/cli

changed store test runs Playwright store tests through Turbo

Store test runs use Turbo's task graph and caching instead of running outside it.

What changed ▸
Changed

store test now runs Playwright store tests through Turbo.

@alokai/cli

fixed store deploy retries its docker prerequisite check

A deploy no longer stops because docker was slow to answer for a moment.

What changed ▸
Changed

store deploy retries its docker prerequisite check instead of failing on the first attempt.

@alokai/cli

fixed Dev-mode URLs keep their suffixes, aliased imports resolve, and new stores get next-env.d.ts

You get all three fixes with the CLI version. A store you added before this release still lacks its next-env.d.ts.

What changed ▸
Changed

In dev mode, @alokai/cli keeps the suffixes of the middleware API and SSR URLs, so http://localhost:4000/api is no longer truncated. Aliased imports resolve in the IDE. A new store created with store add gets the next-env.d.ts file its Next.js app was missing.

@alokai/cli

changed A generated project's root manifest gains an alokai script and a new postinstall

No package delivers any of this. yarn alokai <command> comes from that root script, so your project doesn't have it until you add the script yourself.

What changed ▸
Changed

A project generated at 1.1.0 has an alokai script in its root package.json, mapped to alokai-cli. Its postinstall runs a new scripts/init-script.mjs, which copies .env.example to .env.

The generated project no longer gets scripts/lint-stores.mjs at all. scripts/init-script.mjs and scripts/utils.mjs replace it.

changed A generated project's .gitignore covers the yarn install state and generated tsconfigs

Your own .gitignore doesn't change, so git tracks the files store prepare writes into your substores until you add the entries.

What changed ▸
Changed

A generated project's .gitignore now lists .yarn/install-state.gz, oclif.manifest.json, and the autogenerated tsconfig.json files that store prepare writes into substores.

changed A generated project's pre-commit hook runs prettier, and its test:integration takes Playwright options

Both changes are yours to port. cross-env is already in your root package.json, so you have nothing to install for it.

What changed ▸
Changed

Every packages/lint-staged-config/*.mjs now runs prettier --write before eslint --fix in the pre-commit hook, so a commit reformats as well as lints.

In apps/playwright/package.json, test:integration becomes cross-env playwright test ${PLAYWRIGHT_OPTIONS:-""}. That's what lets the new --turbo-option flag reach Playwright.

fixed Four tooling packages carry fixes of their own

All four reach you the next time you generate a project or install a module, not through a dependency you declare.

What changed ▸
Changed

@vsf-enterprise/file-modifier 3.1.0 creates a missing .env file before it modifies it, instead of failing. @vsf-enterprise/module-kit 3.1.1 fixes the CMS module installation schema and changes how the kit is bundled. @alokai/boilerplate-integration 1.1.0 fixes AI context file paths that pointed at directories that don't exist.

@vsf-enterprise/storefront-cli 3.0.2 no longer validates --version up front. It accepts any string, and an unknown one now errors with the list of available versions. It also installs the version package inside node_modules in its temp directory, and its manifest gains a dependency that was missing.

@vsf-enterprise/file-modifier@vsf-enterprise/module-kit@alokai/boilerplate-integration@vsf-enterprise/storefront-cli
BigCommerce1 change

fixed The BigCommerce product API stops throwing on null product fields

A catalogue with incomplete product data no longer takes the request down.

What changed ▸
Changed

@vsf-enterprise/bigcommerce-api 8.0.1 no longer throws TypeError: Cannot read properties of null (reading 'toLowerCase') when a product's condition is null or undefined. It also tolerates a missing product availability status and a product option with no displayName.

@vsf-enterprise/bigcommerce-api
SmartEditAction needed2 changes

changed SmartEdit resolves component references before normalization Action needed

If you override a SmartEdit normalizer that resolves references itself, it now does that work twice, on data that's already resolved. Drop that logic and read the resolved components from the input.

step →
What changed ▸
Why

Every normalizer had to resolve component references itself, although the API can resolve them once before it hands the data over.

Changed

@vsf-enterprise/smartedit-api 4.0.0 resolves component references before normalization instead of during it. Your normalizers receive components whose references are already resolved.

getReferenceFieldsForComponent now accepts object-style reference definitions. { type: "string", path: "fieldName" } is now the recommended form, and plain strings still work. It also supports dot-notation nested paths such as slides.componentId or sections.rows.cells.componentId.

@vsf-enterprise/smartedit-api

fixed SmartEdit normalizers fix nested resolution, slot placement and urlLink

Nested component resolution changes with the bump. The slot placement fix lives in the default normalizePage, so a page template that looked wrong under 3.0.0 renders as authored unless you override normalizePage.

What changed ▸
Changed

In 4.0.0, nested components resolve recursively. normalizePage places slots by their position rather than by their name, so they land in the right place in the page template. normalizeComponent returns urlLink.

@vsf-enterprise/smartedit-api

On this page