1.4
stricter typing for extensions that override built-in API methods, context.api deprecated, and Compass 1.0
Showing every integration. Set your stack in Preferences and this page hides what isn't yours.
20.* || >=22.14.01.4.0 tightens a type. @alokai/connect 1.2.0 constrains ApiClientExtension, so a middleware extension that overrides a built-in API method loosely stops typechecking. That's a build break, not a warning. In the same release, context.api is deprecated in favour of await context.getApiClient() and will be removed in the next major, and Compass ships its first installable release.
The patches that follow introduce a regression and revert it. 1.4.1 rewrites the middleware dev script the CLI composes and mis-quotes it, so store dev exits with a success status and starts no server. 1.4.2 removes that wrapper and asks you to undo 1.4.1's workaround. It also drops NODE_ENV=development from the composed start:standalone, which takes .env away from store start for every project that adopted 1.4.0's environment loader, and 1.4.3 puts it back.
1.4.5 moves the Nuxt storefront onto module auto-imports, which quietly breaks the next module you install onto a nuxt.config.ts written before it. The line closes with fixes you copy in by hand. Two releases here install core packages identical to the release before them, so version upgrade can't see 1.4.4 or 1.4.6 at all and carries you past both.
Highlights
Overriding a built-in API method now has to keep its original signature
@alokai/connectA middleware extension could override a built-in API method with arguments or a return type that didn't match the original, and it still compiled.
ApiClientExtension is now a type, not an interface. Its API parameter must extend ApiMethods, where it used to accept any. A non-namespaced extension typed ApiClientExtension<Endpoints> must declare each built-in method it overrides with the integration's own signature.
Your middleware stops typechecking after the upgrade if any extension overrides a built-in method loosely. The commonest cases are an override that takes fewer arguments than the original and one that returns a widened object. An extension typed ApiClientExtension with no type argument isn't affected.
Two more cases are worth searching for. interface MyExtension extends ApiClientExtension<...> no longer compiles. An extension that sets isNamespaced: true now gets Record<string, ...> typing and can't use API to override base methods at all.
context.getApiClient() can be called with no arguments, and context.api is on its way out
@alokai/connectTo reach the current integration's client, you used context.api, which gave you no types, or called getApiClient() with the integration's name and typed the result by hand.
context.getApiClient() with no arguments returns the current integration's client, typed from that integration's API, CONFIG, and CLIENT types. To call another integration, you still pass its name as the first argument. Extension methods still need generics: await context.getApiClient<Endpoints & { unified: UnifiedEndpoints }>().
Nested getApiClient() calls, which used to error, now work. context.api is deprecated and will be removed in the next major version.
Custom methods and extensions that use context.api keep working through the whole 1.x line, so you can move at your own pace. You'll still have to change each of those call sites before the next major. The replacement is a two-line edit per call site, and it gives you types where context.api gave you none.
Compass ships its first installable release
@alokai/compass@alokai/cli-plugin-compassCompass had no published packages, so you couldn't install it into your project as a module.
@alokai/compass 1.0.0 and @alokai/cli-plugin-compass 1.0.0 are the first published releases of both packages. Neither package name existed at 1.3.3. The compass module is installable from this release.
The runtime offers a medium model choice in actions, an optional schema on defineStaticTool(), and correct defineConfig typing, including the logger. It can also expose an MCP server that you can register as a ChatGPT app.
You install @alokai/cli-plugin-compass through the CLI's plugin mechanism, not as a dependency in a manifest. The new @oclif/plugin-plugins dependency in @alokai/cli 2.3.0 adds that mechanism.
There's nothing to migrate, and nothing in your project changes until you install the module. The module brings everything Compass needs, so you don't add its dependencies by hand. That's why a freshly generated 1.4.0 project has react-markdown, remark-gfm, tailwind-merge, and zod in its manifests and yours doesn't.
An integration you generated from the boilerplate is pointing at TypeScript it cannot run
@alokai/boilerplate-integrationThe boilerplate pointed a generated integration at its TypeScript source. That path resolves in development mode, but in production mode the middleware fails to load the integration.
Every boilerplate template variant - graphql, openapi, rest-api, sdk-proxy - now emits location: './lib/integrations/<name>/index.server.js', the transpiled output. It used to emit location: './integrations/<name>/index.server.ts', the TypeScript source.
The fix is in the template, and the upgrade doesn't touch the file the template already wrote in your project. If you generated an integration with ./node_modules/.bin/alokai-cli integration generate on 1.3.3 or earlier, your apps/storefront-middleware/middleware.config.ts still names the .ts path. Until you change it to the .js path, the middleware fails to load that integration in production mode.
All changes by area
Every change in 1.4 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.3.3 to 1.4.6 collects the migration steps for the whole line.
Alokai ConnectAction needed12 changes
changed Overriding a built-in API method now has to keep its original signature highlight Action needed
Your middleware stops typechecking after the upgrade if any extension overrides a built-in API method loosely. An extension typed ApiClientExtension with no type argument isn't affected. Two more cases are worth searching for: interface MyExtension extends ApiClientExtension<...> no longer compiles, and an extension that sets isNamespaced: true can't use API to override base methods at all.
What changedWhy, and what changed ▸
A middleware extension could override a built-in API method with arguments or a return type that didn't match the original, and it still compiled.
ApiClientExtension is now a type, not an interface, and its API parameter must extend ApiMethods instead of accepting any. A non-namespaced extension typed ApiClientExtension<Endpoints> must declare each built-in method it overrides with the integration's own signature.
@alokai/connectdeprecated context.getApiClient() can be called with no arguments, and context.api is on its way out highlight
Code that uses context.api keeps working through the whole 1.x line, so you can move at your own pace. You'll still have to change each of those call sites before the next major.
What changedWhy, and what changed ▸
To reach the current integration's client, you used context.api, which gave you no types, or called getApiClient() with the integration's name and typed the result by hand.
context.getApiClient() with no arguments returns the current integration's client, typed from that integration's API, CONFIG, and CLIENT types. To call another integration, you still pass its name first, and extension methods still need generics. Nested getApiClient() calls, which used to error, now work. context.api is deprecated and will be removed in the next major version.
@alokai/connectchanged Alokai's own integration packages moved off context.api
Your own code doesn't have to make the same move for the upgrade to work.
What changedWhy, and what changed ▸
The CMS and SmartEdit API clients call getApiClient() internally instead of the deprecated context.api. So do the unified API layers for BigCommerce, commercetools, Magento, SAP Commerce Cloud, and Salesforce Commerce Cloud.
@vsf-enterprise/amplience-api@vsf-enterprise/bloomreach-content-api@vsf-enterprise/builderio-api@vsf-enterprise/cms-mock-api@vsf-enterprise/contentful-api@vsf-enterprise/contentstack-api@vsf-enterprise/smartedit-api@vsf-enterprise/storyblok-api@vsf-enterprise/unified-api-bigcommerce@vsf-enterprise/unified-api-commercetools@vsf-enterprise/unified-api-magento@vsf-enterprise/unified-api-sapcc@vsf-enterprise/unified-api-sfccdeprecated ContextualizedEndpoints is deprecated in favour of Endpoints
Both names are still exported at 1.4.0, so your existing imports of the old name still compile.
What changedWhy, and what changed ▸
The ContextualizedEndpoints type is deprecated in favour of Endpoints.
@vsf-enterprise/algolia-api@vsf-enterprise/builderio-api@vsf-enterprise/coveo-api@vsf-enterprise/sanity-apiadded A type-safe data federation helper for multi-integration custom methods
An existing project doesn't have the file, and no copy of it is right for you as is, because the map names your integrations. If the file is missing when a module installs, the install doesn't fail. It leaves you a stub with one unused import and no IntegrationContextMap to extend.
What changedWhy, and what changed ▸
A custom method that reads from several integrations had to annotate every getApiClient() call site by hand to get types.
getTypedApiClient in apps/storefront-middleware/integrations/typedApiClient.ts gives getApiClient() full autocomplete and typechecking. You declare each integration's context and its namespaced extensions once, in a local IntegrationContextMap.
Every store template ships the file pre-configured with its own integrations and extensions. The CMS and search modules register themselves in it during add-module, from @vsf-enterprise/module-kit 4.1.0.
@vsf-enterprise/module-kitadded Middleware handles streamed responses from third-party services
What changedWhy, and what changed ▸
The middleware handles a streamed response from a third-party service, so it can process a large payload as it arrives instead of buffering it whole.
@alokai/connectadded Body-parser limits can be set per route
A file-upload endpoint can accept larger bodies than the default, while every other route keeps a tight limit.
What changedWhy, and what changed ▸
You set the body-parser limit per route with a function that receives the route's integration and function name: createServer(config, { bodyParser: ({ functionName, integrationName }) => ({ limit: '4000kb' }) }).
@alokai/connectadded middlewareModule gains built-in POST body compression
What changedWhy, and what changed ▸
middlewareModule in @alokai/connect/sdk can compress POST bodies. Compression is opt-in per call, with prepareConfig({ compression: { algorithm: 'gzip' } }).
@alokai/connectadded A global errorHandler applies to every integration
What changedWhy, and what changed ▸
You can declare a global errorHandler once in middleware.config.ts, and it applies to every integration. A per-integration errorHandler still overrides it. The order is the integration's own handler, then the global one, then the built-in default.
@alokai/connectfixed Body-parser errors reach your custom error handlers
What changedWhy, and what changed ▸
Body-parser errors, such as invalid JSON in a request body, go to your custom error handlers instead of bypassing them.
@alokai/connectadded Request latency and error-rate metrics for the middleware and each integration
@alokai/instrumentation is new to most projects and optional. Add it only if you adopt the metrics.
What changedWhy, and what changed ▸
Request latency and error-rate metrics are available for the middleware and for each integration, with no per-method setup. They come with @alokai/connect and @alokai/instrumentation 1.1.0.
@alokai/connect@alokai/instrumentationfixed Nuxt production builds stop failing to resolve pako highlight 1.4.3
If you run a Nuxt storefront with SDK payload compression, the bump to @alokai/connect 1.2.1 fixes your production build, and nothing in your code changes. Next.js projects were never affected.
What changedWhy, and what changed ▸
A Nuxt production build with SDK payload compression failed to resolve pako, while dev worked.
@alokai/connect imports pako through its default export. pako ships CommonJS, and the named imports it used before don't survive Nuxt's production bundling.
@alokai/connectStorefrontAction needed10 changes
added A centralized environment loader keeps .env out of production
The CLI wrote these files into your project once, so the upgrade doesn't bring any of this. Adopting it takes four coordinated edits. If you skip the two NODE_ENV edits for start:standalone, yarn start:standalone runs with no environment at all.
What changedWhy, and what changed ▸
A top-of-file import 'dotenv/config' loads a .env in every environment, production included, so a committed .env can reach a deployment.
A newly generated project loads environment variables through apps/storefront-middleware/src/config/env.ts. It imports dotenv only when NODE_ENV is development or test, and returns {} otherwise. src/index.ts calls await loadEnv() and then dynamically imports ../middleware.config.js, in place of the top-of-file import 'dotenv/config'.
Two settings get NODE_ENV to the loader under start:standalone, because turbo would otherwise strip it. turbo.json has "passThroughEnv": ["NODE_ENV"] on the start:standalone task. The middleware's own start:standalone script sets NODE_ENV=development.
changed store dev keeps its logs across recompilation
The upgrade doesn't rewrite your own apps/storefront-middleware/package.json, so to keep the logs, take the whole edit into it. Taking only half of it doesn't work.
What changedWhy, and what changed ▸
store dev cleared the terminal on every recompilation, so earlier logs were lost.
A project generated at 1.4.0 sets the middleware dev script to tspc && concurrently --raw "tspc --preserveWatchOutput --watch" "NODE_ENV=development tsx watch --clear-screen=false src/index.ts". The two flags keep the log history. The leading tspc transpiles the app before the watchers start.
fixed The image-overlay CMS banner is served a full-bleed image
A full-bleed banner is no longer served a 300px image. To get the fix, copy the file into your project - that's the whole change.
What changedWhy, and what changed ▸
In the Next.js app, components/cms/page/banner.tsx renders an image-overlay CMS banner with fill and sizes="100vw". Before, it used a fixed height={300} width={300}. The other layout types keep the fixed dimensions.
changed A generated middleware config is checked against MiddlewareConfig, and its build gets more heap
If your middleware build has started running out of memory, the heap setting is worth copying into your own build script.
What changedWhy, and what changed ▸
A generated apps/storefront-middleware/middleware.config.ts ends with } satisfies MiddlewareConfig, using the type imported from @alokai/connect/middleware. The middleware's build script runs tspc under NODE_OPTIONS="--max-old-space-size=8192".
fixed Newly generated projects pin @alokai/connect exactly - your own caret range still blocks version upgrade highlight Action needed 1.4.1
The upgrade doesn't rewrite your manifests, so a caret range on @alokai/connect stays and blocks version upgrade once it resolves to 1.2.1. Mixing ranges is worse than a caret alone. An exact pin beside a caret puts two copies of @alokai/connect in the tree, and the CLI throws Detected dependencies installed in multiple versions before it reaches the matrix. If any app manifest declares a ^ or ~ range, pin it to exactly 1.2.0 before you run version upgrade.
What changedWhy, and what changed ▸
version check and version upgrade abort when the installed @alokai/connect doesn't exactly match the version the compatibility matrix names. @alokai/connect 1.2.1 is published, so a caret range re-resolves past the version the matrix names.
In a project generated at this release, apps/storefront-middleware/package.json and apps/playwright/package.json declare "@alokai/connect": "1.2.0" instead of "^1.2.0". The Next.js and Nuxt manifests still carry "^1.2.0", even in a new project.
changed The Nuxt header markup gets a single root element 1.4.3
The upgrade doesn't change Header.vue, because the file was written into your project when it was created. Only newly generated projects get this change.
What changedWhy, and what changed ▸
In apps/storefront-unified-nuxt/components/ui/Header.vue, the NuxtLazyHydrate/UiOverlay block that holds the search SfModal moves inside UiNavbarTop. The template now has a single root element instead of two.
changed The logged-in account button renders as navbar text 1.4.3
In a newly generated project, the account button shows as neutral text on the navbar instead of a white square icon button. The upgrade doesn't change AuthDropdown.vue, because the file belongs to your project.
What changedWhy, and what changed ▸
The UiButton trigger in apps/storefront-unified-nuxt/components/ui/NavbarTop/AuthDropdown.vue drops its SfIconPerson icon and its square and variant="tertiary" props. An explicit class list styles it instead.
changed UserSettingsButton passes its content through an explicit default slot 1.4.3
The upgrade doesn't change UserSettingsButton.vue, because the file belongs to your project. Only newly generated projects get this change.
What changedWhy, and what changed ▸
apps/storefront-unified-nuxt/components/ui/UserSettingsButton.vue wraps its {{ locale }} / {{ getCurrencyLabel(currency) }} content in an explicit <template #default>. Before, it passed that content as implicit slot content.
changed The Nuxt dev server stops warning about duplicated imports highlight 1.4.5
These files were written into your project when it was created, and no upgrade rewrites them, so your dev server keeps printing the warnings until you mirror the change. Deleting the barrels is up to you, but if you do, rename Notification too - as an auto-imported type it collides with the DOM's own Notification. Next.js projects have nothing here. Only the barrel cleanup is optional: the step's imports.dirs edit and @sf-modules/ import repair are both required before your next module install.
What changedWhy, and what changed ▸
Your Nuxt dev server printed duplicate-import warnings. Nuxt already auto-imports everything under composables/**, so a barrel that re-exports the same symbol registers it a second time.
47 barrel index.ts files are deleted from apps/storefront-unified-nuxt/composables/** and from the Nuxt source of the CMS, Coveo, quick-order, re-order, register-b2b and SAP ASM modules. apps/storefront-unified-nuxt/nuxt.config.ts adds sf-modules/**/composables/** and sf-modules/**/utils/** to its imports.dirs.
The Notification type in composables/useNotification/types.ts is renamed to UiNotification. components/Notifications/types.ts and NotificationFactory.vue take it from the auto-import instead of an import type.
changed Nuxt module source published from here on needs a nuxt.config.ts your project does not have highlight Action needed 1.4.5
If you install or reinstall a Nuxt storefront module after this release onto a nuxt.config.ts written before it, the build fails on unresolved names, and nothing in the error points back here. The module's components reference composables that Nuxt never registers. Your installed module source is untouched, so nothing breaks today. Any of your own code that does import { useAsmAgent } from '@sf-modules/sap-asm' stops resolving as soon as you take the new source.
What changedWhy, and what changed ▸
Nuxt module source from this release onward expects Nuxt to supply its composables through sf-modules/**/composables/** in imports.dirs. The CLI writes that entry only when it creates a project or a store, and no module's install.js adds it.
The Nuxt source of the storefront modules drops its explicit composable imports. The SAP ASM module's Nuxt entry point no longer has export * from './composables', so @sf-modules/sap-asm no longer re-exports useAsmAgent, useAsmUi, useSessionTimer, useCustomer360, useBindCart, useCustomerSuggestions or useEmulation. Its own components stop importing them.
Quick Order's accordions, Re-order's confirmation modal, B2B registration's useRegisterCustomer, Coveo's ten composables and the seven CMS modules' [...slug].vue pages lose their explicit imports the same way.
CLI & toolingAction needed15 changes
fixed An integration you generated from the boilerplate is pointing at TypeScript it cannot run highlight Action needed
The upgrade doesn't touch an integration you already generated. If you generated one on 1.3.3 or earlier, your apps/storefront-middleware/middleware.config.ts still names the .ts path, and the middleware fails to load that integration in production mode until you point it at the .js path.
What changedWhy, and what changed ▸
The boilerplate pointed a generated integration at its TypeScript source. That path resolves in development mode, but in production mode the middleware fails to load the integration.
Every boilerplate template variant - graphql, openapi, rest-api, sdk-proxy - now emits location: './lib/integrations/<name>/index.server.js', the transpiled output, instead of a path to the TypeScript source.
@alokai/boilerplate-integrationadded @alokai/cli gains the plugins command family
It's what makes @alokai/cli-plugin-compass installable. A plugin installed this way lives in the CLI's own store, not in node_modules or yarn.lock.
What changedWhy, and what changed ▸
@alokai/cli 2.3.0 depends on @oclif/plugin-plugins. It adds the plugins command family - plugins install, plugins uninstall, plugins update, and the rest.
@alokai/clichanged integration generate and extension generate abort on a version mismatch
There's no flag to skip the check. If either command refuses to run, reconcile the version in your root package.json.
What changedWhy, and what changed ▸
integration generate and extension generate abort with Command aborted due to Alokai version mismatch. when the project's version can't be matched against the Console compatibility matrix.
@alokai/clichanged version check warns instead of failing, and matrix fetch errors are handled gracefully
A generated project's dev and postinstall scripts both run version check, so a mismatch no longer stops yarn dev or an install.
What changedWhy, and what changed ▸
A version mismatch in version check prints a warning and lets the command finish. Before, the command failed. The CLI also handles errors more gracefully when it fetches the compatibility matrix from the Console API.
@alokai/clifixed Integration names may contain digits
You can name an integration sf-b2b or integration-123.
What changedWhy, and what changed ▸
The kebab-case check on integration names accepts lowercase letters and digits. Before, a digit anywhere in the name failed the check.
@alokai/boilerplate-integrationfixed version upgrade cleans .out, so it stops failing on a duplicate playwright workspace
What changedWhy, and what changed ▸
./node_modules/.bin/alokai-cli version upgrade no longer fails with There are more than one workspace with name "playwright". The duplicate workspace came from the .out directory, and the upgrade now cleans it.
@alokai/clichanged The AI agent context files a new project receives were rebuilt
The upgrade leaves an existing project's AI files in place: it keeps the old ai/ layout and gets no editor rules file. Only an AI coding agent reads these files, so the old set is stale guidance, not a defect.
What changedWhy, and what changed ▸
@vsf-enterprise/storefront-cli 3.1.2 copies the AI agent context files into a new project as they are, instead of generating them at creation time. A project generated at 1.4.0 gets three editor rules files it didn't get before: .cursorrules, .windsurfrules, and .github/copilot-instructions.md.
It also gets an ai/ directory of nine topic guides: project-context.md, code-style.md, development-guide.md, frontend-guide.md, middleware-guide.md, multistore-guide.md, testing-guide.md, git-conventions.md, and README.md. This set replaces the old ai/README.md, ai/general-rules.md, ai/frontend/{nextjs,nuxt}/index.md, and ai/integrations/<platform>/index.md layout. It doesn't extend it.
@vsf-enterprise/storefront-cliadded module-kit gains visitors that register a module in typedApiClient.ts
The CMS and search modules now use these visitors during add-module.
What changedWhy, and what changed ▸
@vsf-enterprise/module-kit 4.1.0 adds createAddExtensionToTypedApiClientVisitor and createAddIntegrationToTypedApiClientVisitor. With them, a module's install.js can register the module in a project's typedApiClient.ts.
@vsf-enterprise/module-kitchanged store dev stops starting the middleware until you re-quote its dev script highlight Action needed 1.4.1
If your middleware dev script contains a double quote, store dev now exits cleanly with no middleware on the port. The first quote closes sh -c early, so concurrently runs a one-shot tspc and exits. Only a dev script with no double quotes survives - the shape generated at 1.0.0. Escape the double quotes in your own dev script.
What changedWhy, and what changed ▸
The composed script was cross-env API_PORT=<port> <your dev script>, so a dev script beginning tspc && split at the &&. The tsx watch process that serves the middleware never saw API_PORT.
@alokai/cli 2.3.1 wraps your middleware dev script in sh -c "..." when it composes .out/<store>/storefront-middleware/package.json. It also moves NODE_ENV=development up beside API_PORT, so cross-env sets both for the whole command. The wrapper doesn't escape the double quotes your dev script already contains.
@alokai/clifixed store dev starts your middleware again - once 1.4.1's quote workaround is out of your file highlight Action needed 1.4.2
If you escaped the double quotes in apps/storefront-middleware/package.json as 1.4.1 asked, undo it. Those escapes now pass through literally, and dev breaks again. Otherwise the fix reaches you on your next compose, with no action.
What changedWhy, and what changed ▸
On 1.4.1, the composed dev script was cut off at the first double quote in your own script, so store dev exited 0 with no middleware listening.
@alokai/cli 2.3.2 no longer inlines your dev script into sh -c "<your dev script>". It writes your original command to a new dev:original script and composes dev as cross-env API_PORT=<port> NODE_ENV=development yarn dev:original. The Next.js and Nuxt apps get the same shape.
@alokai/clichanged store start stops reading your middleware's .env highlight Action needed 1.4.2
If your middleware uses 1.4.0's loader, it starts with no environment and fails on whatever config value it needs first. The start command requires a build and doesn't recompose, so the change lands the first time you run store build or store test after the upgrade. Editing start:standalone in your own manifest doesn't help, because compose overwrites that key outright. Set NODE_ENV=development in the environment of the start command instead, and check that the start:standalone task in your root turbo.json lists NODE_ENV in passThroughEnv - turbo strips it otherwise. Projects that never adopted 1.4.0's loader still do import 'dotenv/config' in middleware.config.ts, which is unconditional, and are unaffected.
What changedWhy, and what changed ▸
The environment loader 1.4.0 introduced reads .env only when NODE_ENV is development or test. This release drops that variable from the composed start script, so a middleware on that loader comes up with no environment at all.
The composed middleware start:standalone is now cross-env API_PORT=<port> yarn start, without NODE_ENV=development. It carried the variable at 1.4.0 and 1.4.1.
@alokai/clifixed Your middleware reads its .env again under store start highlight 1.4.3
A project generated at 1.4.0 or later has apps/storefront-middleware/src/config/env.ts and came up with an empty environment on 1.4.2. A project upgraded through those releases usually declined that loader and still does an unconditional import 'dotenv/config', which 1.4.2 never affected. Either way, this release restores the variable, and neither shape is worse off.
The fix reaches you through the composed copy on your next compose, which store dev, store build and store test all do by default and store start doesn't. If you worked around 1.4.2 by setting NODE_ENV=development around the start command and adding it to passThroughEnv in turbo.json, you don't have to undo any of it. It's redundant, not wrong. The composed value carries NODE_ENV=development at every tag from here through 2.4.1.
What changedWhy, and what changed ▸
On 1.4.2, the composed middleware start:standalone lacked NODE_ENV=development, so every project on 1.4.0's loader started with an empty environment.
The composed middleware start:standalone is cross-env API_PORT=<port> NODE_ENV=development yarn start again.
@alokai/cli@vsf-enterprise/storefront-clifixed Nuxt's standalone server and its Playwright harness load your .env highlight Action needed 1.4.3
The composed start:standalone reaches you on your next compose, with no edit. Your Nuxt integration tests don't get the fix on their own. apps/playwright/setup/framework/nuxt/server.ts was written into your project when it was created, and no upgrade rewrites it, so add -r dotenv/config to its server start line yourself.
What changedWhy, and what changed ▸
The built Nitro server never read .env on its own. Anything that started the built server ran without the values you declared only in that file.
The composed Nuxt start:standalone is now cross-env <urls and port> node -r dotenv/config .deploy/server/index.mjs. The Nuxt server factory the Playwright harness uses, apps/playwright/setup/framework/nuxt/server.ts, gets the same -r dotenv/config. The composed dev script doesn't change in this release.
@alokai/clichanged Your project can now install one TypeScript instead of three highlight 1.4.5
The upgrade leaves your root package.json, your app manifests and packages/tailwind-config alone, so you keep the TypeScript you have. Your next yarn install adds a second typescript beside it, because @alokai/cli 2.3.4's ^5.4.5 no longer matches your pinned copy exactly. Nothing fails if you leave it that way. Collapsing back onto one copy has a cost: the root resolutions entry overrides your apps' pins, so adopting it compiles your code with TypeScript 5.9 - five minor versions newer than 5.4, three newer than the 5.6 the Next.js app pins in a project generated at 1.3.0 or later - and those minors surface errors that the older compilers accepted.
What changedWhy, and what changed ▸
A project generated at 1.4.4 installed three copies of TypeScript side by side - 5.4.5, 5.6.2 and 5.9.3.
@alokai/cli, @alokai/cli-plugin-compass and @vsf-enterprise/storefront-cli depend on typescript ^5.4.5 instead of the exact 5.4.5. The generated project adds a "typescript" entry to the resolutions block of its root package.json, and its app manifests move to 5.9.3. A project generated at 1.4.5 resolves exactly one TypeScript, 5.9.3.
@alokai/cli@alokai/cli-plugin-compass@vsf-enterprise/storefront-clifixed A new project's root package.json no longer keeps the resolutions entry of the framework you didn't pick 1.4.5
The fix applies only while create generates a project, so an existing project is unaffected either way.
What changedWhy, and what changed ▸
When create strips the frontend framework you didn't pick, it now also removes that framework's resolutions entry from the root package.json. Before, it logged the removal but never saved the file.
@vsf-enterprise/storefront-cliCompass1 change
added Compass ships its first installable release highlight
There's nothing to migrate, and nothing in your project changes until you install the Compass module. The module brings the dependencies Compass needs, which is why a freshly generated 1.4.0 project has react-markdown, remark-gfm, tailwind-merge, and zod in its manifests and yours doesn't.
What changedWhy, and what changed ▸
Compass had no published packages, so you couldn't install it into your project as a module.
@alokai/compass 1.0.0 and @alokai/cli-plugin-compass 1.0.0 are the first published releases of both packages, and the compass module is installable from this release. You install the plugin through the CLI's plugin mechanism, not as a dependency in a manifest. The new @oclif/plugin-plugins dependency in @alokai/cli 2.3.0 adds that mechanism.
@alokai/compass@alokai/cli-plugin-compassRedis1 change
added redis-sdk gains createClient and a mock server option
The package is optional. Add it only if you connect to Redis from the middleware.
What changedWhy, and what changed ▸
@vsf-enterprise/redis-sdk 2.1.0 adds createClient, which connects to a Redis server from inside the storefront-middleware app. An option replaces the real server with a mock.
@vsf-enterprise/redis-sdkSAP Commerce Cloud2 changes
fixed getProducts returns the products it did fetch
What changedWhy, and what changed ▸
When any requested ID or SKU is missing, getProducts returns every product it fetched successfully. Before, it returned an empty array. It logs each failed lookup as a warning.
@vsf-enterprise/unified-api-sapccadded sapcc-api exports the ApiMethods type
It's the type to pass in ApiClientExtension<ApiMethods> if the package exports nothing else that fits, now that the extension type constrains its parameter.
What changedWhy, and what changed ▸
@vsf-enterprise/sapcc-api 10.1.0 exports the ApiMethods type.
@vsf-enterprise/sapcc-apicommercetools1 change
added Range faceting for commercetools
Range facets carry prices in centAmount, so format them before you display them.
What changedWhy, and what changed ▸
To add a range facet, declare type: 'range' with a ranges array on an entry in configuration.faceting.availableFacets in your middleware config. Then filter with searchProducts({ facets: { price: ['5000-10000', '15000-*'] } }).
Values come back in "from-to" form with "from - to" labels, and an open-ended range as "from - ". The RangeFacetResult type added to FacetResultValue ships in @vsf-enterprise/commercetools-types 3.0.1.
@vsf-enterprise/commercetools-api@vsf-enterprise/commercetools-typesMagento 22 changes
fixed config.customOptions accepts a partial Apollo client config 1.4.4
You can pass only the options you want to override, and your config typechecks. Runtime behavior doesn't change, and a config that already compiled still compiles.
What changedWhy, and what changed ▸
config.customOptions is now typed Partial<ApolloClientOptions<any>> instead of ApolloClientOptions<any>.
@vsf-enterprise/magento-apifixed unified-api-magento exports four types that unblock declaration emit 1.4.6
Re-exporting the result of createUnifiedExtension from your own code no longer fails with TS2742. Nothing to change in your code - bump the package and the error goes away.
What changedWhy, and what changed ▸
@vsf-enterprise/unified-api-magento now exports the ProductWithTypeName, ProductTypeName, CartItemWithTypeName and CartItemTypeName types from its entry point.
@vsf-enterprise/unified-api-magentoContentstackAction needed3 changes
changed Contentstack gains Visual Builder, and live preview now needs an explicit opt-in Action needed 1.4.3
If you call initLivePreview, add enable: true to each call. Without it, the call returns a no-op and fails silently: there's no error and no log, and the editor never updates.
Then run your typecheck. The argument you pass to initLivePreview is now checked against v4's own init config, so a key you passed under v2 that v4 no longer names is a typecheck error at the call site.
What changedWhy, and what changed ▸
The Contentstack SDK didn't support Contentstack Visual Builder, and it used v2 of @contentstack/live-preview-utils.
@vsf-enterprise/contentstack-sdk 6.0.0 supports Contentstack Visual Builder. The new mode: 'builder' and editButton: { enable: true } options drive the "Start editing" button. You can set stackSdk, stackDetails, and clientUrlParams once in contentstackModule({ ... }), and a value you pass to an initLivePreview call overrides them.
The same release moves @contentstack/live-preview-utils from v2 to v4. initLivePreview now does nothing until you pass enable: true. Before, it detected the live-preview iframe and initialized itself.
@vsf-enterprise/contentstack-sdkremoved The deprecated Contentstack extractComponents util is removed Action needed 1.4.3
If your code calls extractComponents, it survives the version bump and then fails at typecheck, and at runtime as extractComponents is not a function. There's no drop-in replacement. Move each call site onto the unified page that sdk.contentstack.unified.getPage(...) returns.
What changedWhy, and what changed ▸
extractComponents was deprecated. It turned raw Contentstack entries into { componentName, props } pairs, and the unified page that sdk.contentstack.unified.getPage(...) returns already carries that shape.
@vsf-enterprise/contentstack-sdk 6.0.0 no longer exposes extractComponents. The module's utils object now carries only getImageObject and initLivePreview. The util's own deprecation comment said it would be removed in August 2028.
@vsf-enterprise/contentstack-sdkfixed Contentstack live-edit tags survive normalization 1.4.3
The Live Edit Tags setup reads the $ field, so it now finds that field on normalized content whenever livePreview.enable is true. An entry whose styles field isn't an array no longer throws in the normalizer.
What changedWhy, and what changed ▸
@vsf-enterprise/contentstack-api 6.0.3 keeps Contentstack's $ live-edit-tags field on normalized entries and their children. Before, normalization stripped it. getContent and unified.getPage attach these fields whenever livePreview.enable is true in your config, not only when the request carries a live-preview query.
The normalizer also checks that styles is an array before it maps it.
@vsf-enterprise/contentstack-apiSmartEditAction needed4 changes
fixed smartedit-api exports ApiMethods and restores two legacy endpoints
What changedWhy, and what changed ▸
@vsf-enterprise/smartedit-api 5.1.0 exports the ApiMethods type. It also restores the legacy getComponentById and getPageById endpoints, which had gone missing.
@vsf-enterprise/smartedit-apifixed SmartEdit fetches nested components in batches of 20 1.4.4
A page with many nested components no longer fails with SAP Commerce Cloud's 414 URI-too-long error. You have nothing to change, and a page that used to fail now loads.
What changedWhy, and what changed ▸
getPage fetches nested components in batches of 20 instead of asking for all of them in one request.
@vsf-enterprise/smartedit-apichanged SmartEdit object reference paths change meaning Action needed 1.4.4
The same config can now put a resolved reference in a different place, and nothing errors. You only see it by looking at a response. If you meant to replace the whole array item, with the ID at a nested key, move the nesting from path into idField: { path: "items", idField: "properties.componentId" } instead of { path: "items.properties", idField: "componentId" }.
String references and the built-in container default are unaffected. With this change, the SmartEdit CMS module's module.json pins @vsf-enterprise/smartedit-api 5.1.1. A project that adopts the module after this release picks up the new version, and one that already adopted it doesn't.
What changedWhy, and what changed ▸
For an object reference with a dotted path, the resolver replaced the whole array item instead of the property that path points at.
For a { type: "object" } entry that getReferenceFieldsForComponent returns, path says where to replace, and idField says where to read the component ID. idField supports dot notation. So { path: "items.properties", idField: "componentId" } used to replace items[i], and now replaces items[i].properties.
@vsf-enterprise/smartedit-apifixed SmartEdit link resolution and a crash guard on empty CMS content Action needed 1.4.6
Copy the three edits into your project by hand. The fix lives in module source that add-module cms-smartedit copied into your project, so no upgrade delivers it, and @vsf-enterprise/smartedit-api 5.1.2 differs from 5.1.1 by its version field alone. Until you copy the edits, SmartEdit links to SAP Commerce Cloud category URLs stay dead and an empty CMS slot still takes the page down.
The code isn't gated on B2B, so B2C storefronts are affected too. Only the Next.js source needs the edits - the module's Nuxt source doesn't change in this release.
step →What changedWhy, and what changed ▸
SmartEdit-authored links that carry a native SAP Commerce Cloud category URL, such as /Open-Catalogue/Hand-Tools/Angle-Grinders/c/1595, rendered as dead links. An empty CMS slot threw Cannot use 'in' operator to search for 'slotId' in undefined and took the page down.
resolveHref in sf-modules/cms-smartedit/components/native/shared/link-wrapper.tsx is now exported. It rewrites a url that contains /c/ into /category/<id>. SeLink in sf-modules/cms-smartedit/components/native/se-link.tsx calls it, instead of rewriting only when SmartEdit supplies a separate categoryCode.
RenderCmsContent in sf-modules/cms-smartedit/components/render-cms-content.tsx returns null for an empty item instead of throwing.
Algolia1 change
added algolia-api exports the Endpoints type
What changedWhy, and what changed ▸
@vsf-enterprise/algolia-api 6.0.1 exports the Endpoints type.
@vsf-enterprise/algolia-apiCI / deployment workflowsAction needed1 change
fixed Your deploy workflow stops running out of disk and heap highlight Action needed 1.4.4
The upgrade doesn't add the action or change your workflow, because both are files your project owns. A deploy that fails with ENOSPC or JavaScript heap out of memory keeps failing until you make the two edits yourself. Projects generated at 1.4.4 or later already have them.
What changedWhy, and what changed ▸
On a GitHub-hosted runner, the deploy job ran out of disk and V8 heap, and failed with ENOSPC or JavaScript heap out of memory.
The project template gains a .github/actions/free-up-space/action.yml action that deletes the runner's preinstalled Android SDK before the build. The deploy job in .github/workflows/continuous-delivery.yml calls it and sets NODE_OPTIONS: "--max-old-space-size=4096" on the 🚀 Deploy store step.
Patches in 1.4.x
1.4.6
26 Jan 2026 · Patch · 4 of 73 packages moved
Two integration fixes, and the larger one arrives in no package at all. The SmartEdit fix is three files of module source that npx @vsf-enterprise/storefront-cli add-module cms-smartedit copied into your project, so the upgrade can't reach them and you apply them by hand. @vsf-enterprise/smartedit-api 5.1.2 doesn't carry the fix - it differs from 5.1.1 by its version field alone.
No core package moved. @alokai/cli, @alokai/connect, @vue-storefront/next and @vue-storefront/nuxt are identical to 1.4.5, so the upgrade command has no work to do here. Those four are all it reads, so it can't tell a 1.4.5 project from a 1.4.6 one and reports 1.4.6 for both.
1.4.5
16 Dec 2025 · Patch · 5 of 73 packages moved
This release does two unrelated things. A newly generated project installs a single TypeScript, 5.9.3, where 1.4.4 installed three side by side, and your own project keeps what it has until you make the same edits. The Nuxt storefront and every Nuxt storefront module drop their composables/** barrel files and rely on Nuxt auto-imports. That silences the dev-server duplicate-import warnings, but module source published from this release onward won't resolve against a nuxt.config.ts written before it.
@alokai/cli 2.3.4 is the only package the upgrade command moves, and it's the only thing this release delivers to an existing project. Everything else lives in files that belong to you.
Your project can now install one TypeScript instead of three
@alokai/cli@alokai/cli-plugin-compass@vsf-enterprise/storefront-cliA project generated at 1.4.4 installed three copies of TypeScript side by side - 5.4.5, 5.6.2 and 5.9.3.
@alokai/cli, @alokai/cli-plugin-compass and @vsf-enterprise/storefront-cli depend on typescript ^5.4.5 instead of the exact 5.4.5. The generated project adds a "typescript" entry to the resolutions block of its root package.json, and its app manifests move to 5.9.3. A project generated at 1.4.5 resolves exactly one TypeScript, 5.9.3.
The upgrade leaves your root package.json, your app manifests and packages/tailwind-config alone, so you keep the TypeScript you have. One thing does change without asking: @alokai/cli 2.3.4's ^5.4.5 no longer matches your pinned copy exactly, so your next yarn install adds a second typescript to yarn.lock beside the one you already resolve. Nothing fails if you leave it that way.
Collapsing back onto one copy is an edit to your root manifest plus every app that pins typescript, and it has a cost. The root resolutions entry overrides your apps' pins, so adopting it compiles your own code with TypeScript 5.9: five minor versions newer than 5.4, three newer than the 5.6 the Next.js app pins in a project generated at 1.3.0 or later. Those minors tightened inference enough to surface errors that the older compilers accepted.
The Nuxt dev server stops warning about duplicated imports
Your Nuxt dev server printed duplicate-import warnings. Nuxt already auto-imports everything under composables/**, so a barrel that re-exports the same symbol registers it a second time.
47 barrel index.ts files are deleted from apps/storefront-unified-nuxt/composables/** and from the Nuxt source of the CMS, Coveo, quick-order, re-order, register-b2b and SAP ASM modules. apps/storefront-unified-nuxt/nuxt.config.ts adds sf-modules/**/composables/** and sf-modules/**/utils/** to its imports.dirs. Each symbol is now registered once.
The Notification type in apps/storefront-unified-nuxt/composables/useNotification/types.ts is renamed to UiNotification. components/Notifications/types.ts and NotificationFactory.vue take it from the auto-import instead of an import type.
These files were written into your project when it was created, and no upgrade rewrites them, so your dev server keeps printing the warnings until you mirror the change. Only a project generated at 1.4.5 or later has the change already. Next.js projects have nothing here.
Deleting the barrels is up to you - do it whenever you like, or not at all. If you do, rename Notification too, because as an auto-imported type it collides with the DOM's own Notification.
The linked step has three parts, and only this barrel cleanup is optional. Its imports.dirs edit and its @sf-modules/ import repair are both required before your next module install, and the step's opening instruction is about them, not about the barrels.
Nuxt module source published from here on needs a nuxt.config.ts your project does not have
Nuxt module source from this release onward expects Nuxt to supply its composables through sf-modules/**/composables/** in imports.dirs. The CLI writes that entry only when it creates a project or a store, and no module's install.js adds it.
The Nuxt source of the storefront modules drops its explicit composable imports. The SAP ASM module's Nuxt entry point no longer has export * from './composables', so @sf-modules/sap-asm no longer re-exports useAsmAgent, useAsmUi, useSessionTimer, useCustomer360, useBindCart, useCustomerSuggestions or useEmulation. Its own components stop importing them, and layouts/root.vue, SessionTimer.vue and the Customer360View panels expect Nuxt to supply the names.
Quick Order's accordions, Re-order's confirmation modal, B2B registration's useRegisterCustomer, Coveo's ten composables and the seven CMS modules' [...slug].vue pages lose their explicit imports the same way.
The CLI writes sf-modules/**/composables/** into apps/storefront-unified-nuxt/nuxt.config.ts and into each store's apps/stores/<store>/storefront-unified-nuxt/nuxt.config.ts when it creates them. The SAP ASM install schema extends components: only, and no module install script changes in this release.
If you install or reinstall a Nuxt storefront module after this release onto a nuxt.config.ts written before it, the build fails on unresolved names, and nothing in the error points back here. The module's components reference composables that Nuxt never registers. Your installed module source is untouched, so nothing breaks today. Any of your own code that does import { useAsmAgent } from '@sf-modules/sap-asm' stops resolving as soon as you take the new source.
1.4.4
8 Dec 2025 · Patch · 4 of 73 packages moved
Two published packages carry a change of their own. The most visible fix is in a file the upgrade can't reach: the deploy job in the generated continuous-delivery.yml workflow ran out of disk and heap on the GitHub runner. If you wrote your own getReferenceFieldsForComponent, read the SmartEdit change closely. path and idField now mean something different for object-type entries, so the same config can resolve to a different shape.
None of the four core packages moves in this release, so the upgrade command has nothing to do for it. The command reads only those four, so it already reads a 1.4.3 project as 1.4.4 and offers to take you past this release instead of to it. Don't take that offer - apply 1.4.4 by hand.
Your deploy workflow stops running out of disk and heap
On a GitHub-hosted runner, the deploy job ran out of disk and V8 heap, and failed with ENOSPC or JavaScript heap out of memory. The job checks out the full history, installs the whole workspace, and then builds and pushes the store's image.
The project template gains a composite action at .github/actions/free-up-space/action.yml. It deletes the runner's preinstalled Android SDK before the build. The deploy job in .github/workflows/continuous-delivery.yml now calls the action, and sets NODE_OPTIONS: "--max-old-space-size=4096" on the 🚀 Deploy store step.
The upgrade doesn't add the action or change your workflow, because both are files your project owns. A deploy that fails with ENOSPC or JavaScript heap out of memory keeps failing until you make the two edits yourself. Projects generated at 1.4.4 or later already have them.
1.4.3
24 Nov 2025 · Patch · 9 of 73 packages moved
The composed start:standalone scripts load your environment again. The middleware regains the NODE_ENV=development 1.4.2 dropped, and Nuxt's standalone server now starts through dotenv/config, which it never did before. @alokai/connect changes how it imports pako, which fixes Nuxt production builds that failed to resolve the module. @vsf-enterprise/contentstack-sdk goes to 6.0.0: live preview now needs an explicit enable: true or it silently does nothing, and the deprecated extractComponents util is gone.
1.4.2 asked you to supply NODE_ENV=development from outside the composed middleware start:standalone. This release puts it back into the composed script, so that workaround is no longer needed.
Your middleware reads its .env again under store start
@alokai/cli@vsf-enterprise/storefront-cliOn 1.4.2, the composed middleware start:standalone lacked NODE_ENV=development, so every project on 1.4.0's loader started with an empty environment.
The composed middleware start:standalone is cross-env API_PORT=<port> NODE_ENV=development yarn start again.
Whether 1.4.2 affected you depends on how your middleware loads its environment. A project generated at 1.4.0 or later has apps/storefront-middleware/src/config/env.ts, which reads .env only when NODE_ENV is development or test. On 1.4.2, that project's composed middleware came up with an empty environment and failed on the first config value it needed.
A project upgraded through those releases usually doesn't have that file, because many projects declined the opt-in loader step in 1.4.0. Its middleware.config.ts still opens with an unconditional import 'dotenv/config', which 1.4.2 never affected. To check which you have, run ls apps/storefront-middleware/src/config/env.ts 2>/dev/null || echo "no loader - 1.4.2 did not affect your environment loading".
Either way, this release restores the variable, and neither shape is worse off. The fix reaches you through the composed copy at .out/<store>/storefront-middleware/package.json, not through a file you edit. It lands on your next compose, which store dev, store build and store test all do by default and store start doesn't.
If you applied 1.4.2's Restore NODE_ENV for the composed standalone start step, by setting NODE_ENV=development around the start command and adding it to passThroughEnv in turbo.json, you don't have to undo any of it. It's now redundant, not wrong. You can stop passing the variable, and the turbo.json entry is harmless if you leave it.
The composed value carries NODE_ENV=development at every tag from here through 2.4.1, so no later release in this series asks you to work around it again.
Nuxt's standalone server and its Playwright harness load your .env
@alokai/cliThe built Nitro server never read .env on its own. On a Nuxt project, anything that started the built server, store start and the integration tests through store test, ran without the values you declared only in that file.
The composed Nuxt start:standalone is now cross-env <urls and port> node -r dotenv/config .deploy/server/index.mjs. Before, it ran node .deploy/server/index.mjs with no preloaded loader. The Nuxt server factory the Playwright harness uses, apps/playwright/setup/framework/nuxt/server.ts, gets the same -r dotenv/config.
This is the start path, not the dev one. The composed dev script doesn't change in this release.
The composed start:standalone reaches you on your next compose, with no edit. Your Nuxt integration tests don't get the fix on their own. apps/playwright/setup/framework/nuxt/server.ts was written into your project when it was created, and no upgrade rewrites it. Your tests keep starting the server without .env until you add -r dotenv/config to its server start line yourself.
Nuxt production builds stop failing to resolve pako
@alokai/connectA Nuxt production build with SDK payload compression failed with a module-resolution error on pako, while dev worked.
@alokai/connect imports pako through its default export. pako ships CommonJS, and the named imports it used before don't survive Nuxt's production bundling.
If you run a Nuxt storefront with SDK payload compression, the bump to @alokai/connect 1.2.1 fixes your production build, and nothing in your code changes. Next.js projects were never affected.
1.4.2
17 Nov 2025 · Patch · 3 of 73 packages moved
One change in @alokai/cli 2.3.2 has two consequences that point opposite ways. It repairs the store dev failure 1.4.1 introduced, but only after you take 1.4.1's quote-escaping workaround back out. It also drops NODE_ENV=development from the composed middleware start:standalone, so store start stops reading .env for every project that adopted 1.4.0's environment loader. Nothing else in the release changes more than a version number.
If you applied 1.4.1's instruction to escape the double quotes in apps/storefront-middleware/package.json, undo it here, or dev breaks in the other direction. If you came from 1.4.0 and skipped 1.4.1, you never had either dev-script problem and have nothing to revert.
store dev starts your middleware again - once 1.4.1's quote workaround is out of your file
@alokai/cliOn 1.4.1, the composed dev script was cut off at the first double quote in your own script, so store dev exited 0 with no middleware listening.
@alokai/cli 2.3.2 no longer inlines your dev script into sh -c "<your dev script>" when it composes .out/<store>/storefront-middleware/package.json. It writes your original command to a new dev:original script and composes dev as cross-env API_PORT=<port> NODE_ENV=development yarn dev:original. The Next.js and Nuxt apps get the same shape: their composed dev ends in yarn dev:original.
The fix reaches you on your next compose, which store dev, store build and store test all do by default. If you applied 1.4.1's instruction to escape the double quotes in apps/storefront-middleware/package.json, undo it. Those escapes now pass through literally, concurrently receives "tspc and --watch" as separate words, and dev breaks again. If you didn't, you have nothing to do.
store start stops reading your middleware's .env
@alokai/cliThe environment loader 1.4.0 introduced reads .env only when NODE_ENV is development or test. This release drops that variable from the composed start script, so a middleware on that loader comes up with no environment at all.
The composed middleware start:standalone is now cross-env API_PORT=<port> yarn start, without NODE_ENV=development. It carried the variable at 1.4.0 and 1.4.1.
If your middleware loads .env through apps/storefront-middleware/src/config/env.ts, nothing in .env is read under store start. The start command requires a build and doesn't recompose, so the change lands the first time you run store build or store test after the upgrade. From then on, the middleware starts with no environment and fails on whatever config value it needs first.
Editing the start:standalone script in apps/storefront-middleware/package.json doesn't help. Compose overwrites that key outright, including the value 1.4.0's environment-loader step asked you to put there. Set NODE_ENV=development in the environment of the start command instead, and check that the start:standalone task in your root turbo.json lists NODE_ENV in passThroughEnv - turbo strips it otherwise. Projects that never adopted 1.4.0's loader still do import 'dotenv/config' in middleware.config.ts, which is unconditional, and are unaffected.
1.4.1
14 Nov 2025 · Patch · 3 of 73 packages moved
Two fixes, and the larger one costs you something. @alokai/cli 2.3.1 rewrites the middleware dev script it composes for each store, and the rewrite is mis-quoted for every dev script that contains a double quote - which is every generated middleware dev script since 1.1.0. After the upgrade, store dev type-checks and exits with a success status instead of starting the middleware, until you re-quote the script in your own project. Nothing tells you it failed except the empty port.
The second fix pins @alokai/connect exactly in two of the manifests a newly generated project gets. The upgrade doesn't touch your own manifests, and a ^ range left in them is what blocks version upgrade later.
The dev-script fix pays off only if you took 1.4.0's instruction to start the dev script in apps/storefront-middleware/package.json with tspc &&. If you skipped that step, you never had the port bug fixed here, but the regression hits you just the same, so you need the same step.
store dev stops starting the middleware until you re-quote its dev script
@alokai/cliThe composed script was cross-env API_PORT=<port> <your dev script>, so a dev script beginning tspc && split at the &&. cross-env set API_PORT for tspc only, and the tsx watch process that serves the middleware never saw it.
@alokai/cli 2.3.1 wraps your middleware dev script in sh -c "..." when it composes .out/<store>/storefront-middleware/package.json. It also moves NODE_ENV=development up beside API_PORT, so cross-env sets both for the whole command. The wrapper doesn't escape the double quotes your dev script already contains.
If your dev script contains a double quote, the first one closes sh -c early, and store dev and yarn dev now finish with a clean exit and no dev server on the port. On the script a 1.4.0 project has, sh -c receives tspc && concurrently --raw tspc, so concurrently runs a one-shot tspc and exits. A project that never adopted 1.4.0's tspc && change breaks the same way, one word earlier: sh -c receives concurrently --raw tspc.
Only a dev script with no double quotes in it survives - the shape generated at 1.0.0. Escape the double quotes in your own dev script.
Newly generated projects pin @alokai/connect exactly - your own caret range still blocks version upgrade
version check and version upgrade abort when the installed @alokai/connect doesn't exactly match the version the compatibility matrix names. @alokai/connect 1.2.1 is published, so a caret range re-resolves past the version the matrix names.
In a project generated at this release, apps/storefront-middleware/package.json and apps/playwright/package.json declare "@alokai/connect": "1.2.0" instead of "^1.2.0". Those are the only two files that change. apps/storefront-unified-nextjs/package.json and apps/storefront-unified-nuxt/package.json still carry "^1.2.0" at this release.
@alokai/cli, @vue-storefront/next, and @vue-storefront/nuxt were already declared exactly everywhere, so @alokai/connect is the only core package that changes.
The upgrade doesn't rewrite your manifests, so whatever your project holds today, it keeps. A ^1.2.0 range that re-resolves, on a fresh clone, after a deleted lockfile, or with yarn upgrade, installs 1.2.1 against a matrix entry of 1.2.0, and version upgrade refuses to run.
Mixing ranges is worse. An exact 1.2.0 in one manifest beside ^1.2.0 in another puts two copies of @alokai/connect in the tree, and the CLI throws Detected dependencies installed in multiple versions before it reaches the matrix. If any app manifest declares a ^ or ~ range, pin it to exactly 1.2.0 before you run version upgrade.