Every stable Alokai ecosystem release of 2026, with dates and full notes — shipped continuously, adopted on your schedule.
We operate on a continuous release schedule, so you always have access to our latest features and improvements. But we know your workflow matters — so you have complete control over when to apply updates. Pin the version that suits you and upgrade at your own pace, whenever it best fits your roadmap.
alokai version upgrade) when you're ready — never forced mid-sprint.This page mirrors our private GitHub release registry for the @alokai/ecosystem package — the same source our team watches on your behalf.
onLiveEdit callback receives a ready-to-use livePreviewUrl with the live preview query encoded, and the Next.js integration navigates to it with router.replace instead of router.refresh() so the previewed content is re-fetched correctly.env('NEXT_PUBLIC_*') now returns the correct value on the client during the first render and inside initial useEffect calls. Previously, runtime env vars were undefined until shortly after hydration, which could break integrations that read them eagerly — for example, the SAP CDC module's getCdcConfig() returned no API key on first render and failed to load the Gigya SDK.AlokaiInstrumentation now reliably captures the initial page view and any navigation that happens during page load. Previously, the history-trace script started running after hydration, so the very first page view and any router navigation triggered before that point were not reported.FIXED getProductReferences now normalizes each reference's target via normalizeProductCatalogItem instead of normalizeProduct. The SeProductReferences component renders catalog cards (via ProductCardVertical, which is typed SfProductCatalogItem) — so the data must flow through the catalog-item normalizer chain. With the previous normalizeProduct choice, customer-side addCustomFields.normalizeProductCatalogItem augmentations (e.g. @vsf-modules/compass's required description: string) caused a structural $custom mismatch and failed typecheck in customer projects (ES-2626).
FIXED Improve facet value matching to handle prefixed values (e.g. color-black, size-10) and prefer superZoom image format for gallery and primary images.
Facet normalizer now correctly resolves prefixed facet values by trying exact match first, then suffix match
superZoom format over zoom for highest qualitygetOptions helper falls back to variantOptions when baseOptions is emptyADDED --docker-image-tag flag for store deploy command to allow specifying a custom Docker image tag instead of the auto-generated git commit SHA. Can also be set via the CLI_DOCKER_IMAGE_TAG environment variable.
ADDED defineMocker for recording and replaying outgoing HTTP requests in middleware.
```typescript import { defineMocker } from "@alokai/connect/integration-kit";
const { extension, mocker } = defineMocker({ // Enable or disable the extension entirely (default: true) enabled: process.env.MOCKER_ENABLED === "true", // Initial mode: "idle" | "recording" | "replaying" mode: () => "recording", // Allow real network requests for unmatched hosts during replay allowUnmocked: (host) => host.includes("my-trusted-api.com"), // Control which recorded requests are saved and replayed shouldMock: (call) => !call.scope?.includes("internal-service"), // Preload previously saved recordings (required when mode is "replaying") recordings: () => savedRecordings, // Specify custom call duration delayResponse: (call) => call.duration, // Do something with request paths before matching (e.g. strip dynamic segments) filteringPath: (_call, path) => path.replace(/\/api\/v[0-9]+\//, "/api/"), // Do something with the body before matching filteringRequestBody: (_call, body) => body, // Do something with the recordings (e.g. save them to a file) onRecordingStopped: (recordings, allRecordings) => { console.log({ recordings }); }, });
// Programmatic control (no HTTP requests needed): mocker.record(); // Start recording mocker.replay(); // Start replaying mocker.stop(); // Stop recording or replaying mocker.reset(); // Stop and clear all state mocker.getState(); // Get current state ```
Once registered, the mocker also exposes HTTP endpoints on your middleware server:
| Endpoint | Method | Description |
|---|---|---|
/mocker |
GET | View current state and available handlers |
/mocker/record |
GET | Start recording outgoing HTTP requests |
/mocker/replay |
GET | Start replaying previously recorded requests |
/mocker/stop |
GET | Stop recording or replaying |
/mocker/reset |
GET | Stop and clear all recordings and state |
ADDED Payload size limits for Compass workflows. Text and image content is measured after transforms and trimming, right before the LLM call. Default limits: 200KB text, 1MB images. Configurable per workflow via limits in workflow config.
ADDED Periodic chat history compaction — older messages are summarized while preserving recent context. Opt in via useCompactHistory in the assistant hook or as an SDK parameter.
ADDED Image analysis action and context message rendering — describes images for both chat history and compact chat history.
ADDED Compass batch cart removal and clear cart tools for the chatbot workflow.
ADDED Handle Set-Cookie headers from commerce API responses by intercepting, streaming, and applying them on the client. Compactor tool-call summaries improved to prevent LLM hallucination of IDs and SKUs.
CHANGED Consolidated product search into the main assistant action, removing the separate search-products router step. Category enum strategy for searchProducts tool schema updated accordingly.
CHANGED Compass module: replaced defineDynamicTool with unified defineTool in tool definitions.
CHANGED Compass analytics action no longer accepts the model option.
/c/... and PDP pages under /p/....@vsf-modules/search-bloomreach module and @vsf-enterprise/bloomreach-discovery-api. See package changelogs and docs for details.cms-smartedit now maps the root path / to pageLabelOrId: 'homepage' by default in resolvePages. SmartEdit's default "homepage" label works out of the box on the root route without manual configuration. See migration guide below.FIXED Deploying a new storefront to CI/CD no longer fails due to missing private package access. Switching from the CMS mock to a real CMS provider no longer leaves behind stale mock references in the codebase.
FIXED Updated install.js to target correct file paths after sf-modules refactor (category and product pages). Added replaceAllOrThrow safety guard so install-time regressions throw immediately instead of silently producing broken storefronts.
FIXED Resolved tinyexec version conflict causing MODULE_NOT_FOUND error on global CLI install.
FIXED Deploying a store with --framework nextjs no longer triggers unnecessary nuxt prepare during composition, preventing CI failures caused by unbuilt workspace packages.
getCart tool so the LLM can resolve line item IDs for remove/update operations. Guided selling prompts updated for GPT-5-chat compatibility.cms-smartedit now maps / to pageLabelOrId: 'homepage' by default in resolvePages.
homepage for your storefront's root page (rename it from / if needed).storefront-middleware/sf-modules/cms-smartedit/config.ts:/* ... */
resolvePages: () => ({
+ '/': {
+ pageLabelOrId: 'homepage',
+ },
/* ... */
})
Added @antfu/ni to the generated project's devDependencies. This dependency is required by alokai-cli integration generate and other CLI commands.
For existing projects: Add @antfu/ni manually by running:
yarn add -W -D @antfu/ni
getTypedApiClient now accepts any integration context, not just the primary commerce one. Previously, the function typed its context parameter using the project-specific IntegrationContext from @/types (which resolved to the commerce integration's context type), causing TypeScript errors when calling the helper from within a second integration's methods (e.g. SmartEdit). The parameter is now typed using the base IntegrationContext from @alokai/connect/middleware, which all integration contexts extend.util module in the Nuxt storefront browser build.Add the following to your nuxt.config.ts under the vite key:
vite: {
resolve: {
alias: {
util: 'unenv/node/util',
},
},
},
granularity: "method" in the circuitBreaker config to isolate breakers per API method — a failing endpoint no longer trips the breaker for the entire integration.connectCmsPage across all CMS modules. When the API returns 404, null is passed as page to the consumer instead of silently catching all errors or calling notFound() directly. Non-404 errors now propagate correctly.@storefront-ui/nuxt to 3.2.0, ensuring compatibility with Nuxt 4.extendApiMethods is now optional in defineIntegrationExtension, allowing extensions with only hooks or extendApp.typecheck turbo tasks for frontend apps so yarn typecheck works in generated and multistore projects.CHANGED Update to Tailwind 4 requires some manual changes in the storefronts code. See the migration guide below for more details.
ADDED Circuit Breaker automatically protects your application from cascading failures when backend services become unavailable. When errors exceed a threshold, the circuit breaker blocks requests immediately instead of waiting for timeouts, giving failing services time to recover. Works out of the box with sensible defaults — no code changes required. All circuit breaker events logged with structured metadata. Prometheus metrics for monitoring state transitions and request outcomes. Configurable presets (PRODUCTION, DEVELOPMENT, AGGRESSIVE, TOLERANT, FAST_FAILURE, HARD_FAIL, RELAXED_DEBUG, EXTREME_DEBUG). Please, check Circuit Breaker for more details.
FIXED Default error handler now returns JSON for 5xx server errors (consistent with 4xx responses) instead of a plain text message.
const response = await fetch(url);
if (response.status >= 500) {
- const text = await response.text();
- console.error(text);
+ const body = await response.json();
+ console.error(body.message);
}
CHANGED (Next.js only) Next@16 support
CHANGED Upgraded to Nuxt 4. All Nuxt-related packages now require Nuxt ^4.0.0.
CHANGED Improved error handling in middleware with better type safety and more reliable error responses. Error responses are now more consistent and predictable — if you're catching and handling errors from API calls, you may notice more detailed error information in 4xx responses (validation errors, not found errors, etc.), better structured error objects with proper error types, and improved error messages for authentication and token-related issues.
CHANGED The storefront-middleware app now uses ESM (ECMAScript Modules) instead of CommonJS.
@alokai/connect) normalizeGraphQLError helper for normalizing GraphQL errors from any client (Apollo Client, urql, graphql-request) to HttpError. Maps GraphQL error codes to appropriate HTTP status codes and preserves error metadata. The normalizer is client-agnostic and works without requiring the graphql package as a dependency.@alokai/connect) withData method on HttpError class, useful for adding context to errors without reconstructing the entire error.@alokai/connect) New HTTP Client adapter types for error handling on the middleware layer.@alokai/cli) The alokai-cli store build command now accepts the --skip-compose flag.@vsf-enterprise/sapcc-types) ASM typings are now available in the sapcc-types package.@alokai/connect) Allow headers to accept async functions and promised header objects.@alokai/connect) The InferCustom type alias now falls back to Record<string, unknown> instead of object.@vsf-enterprise/sapcc-api) Migrate to use axiosErrorAdapter from @alokai/middleware-axios-error-adapter.@vsf-enterprise/magento-api) Migrate to use apolloErrorAdapter from @alokai/middleware-apollo-error-adapter.@vsf-enterprise/contentstack-api) Contentstack normalizers now preserve original snake_case field names from the CMS instead of converting them to camelCase. This allows field names in the storefront to match your Contentstack schema, enabling use of auto-generated TypeScript types.@alokai/connect/integration-kit) defineIntegrationExtension factory for creating typed custom extensions with full type inference for API methods, hooks configuration, and extendApp.@vue-storefront/next) Runtime environment variable support via env() function. This replaces the next-runtime-env package with a built-in solution that automatically injects NEXT_PUBLIC_* environment variables into the client-side for runtime access. The new solution provides a unified env() function that works on both server and client, automatic injection of NEXT_PUBLIC_* variables via AlokaiProvider, no additional configuration or props needed, and supports runtime environment changes (e.g., in Alokai Console).@alokai/cli) Support for ni (package manager agnostic tool), enabling automatic detection and usage of the package manager configured in your project (npm, yarn, pnpm, or bun). This allows developers to use their preferred package manager while the CLI automatically adapts to the project's configuration.ProductCardVertical component to accept the product prop directly, eliminating the need for prop drilling from ancestor components.@alokai/connect) Changed lodash to lodash-es for better ESM compatibility.typescript devDependency in playwright app.@alokai/connect/sdk) When using the middlewareModule, it no longer throws when trying to access a method by a non-string property name and returns undefined instead. This avoids errors in edge cases where React's built-in development hooks inspect SDK modules by accessing Symbol properties..cursorrules and .windsurfrules with AGENTS.md in generated projects.@alokai/cli) CLI now detects the package manager binary path more reliably under Yarn Berry (Yarn 3/4).commitlint has been removed from generated projects.@alokai/connect) Fixed CONFIG type inference when providing extensions property in identify functions using the Integration interface. Previously, keyof typeof config.configuration.workflows resolved to string | number | symbol; now it correctly resolves to the literal union (e.g., "a" | "b" | "c").@vsf-enterprise and @alokai package builds.@vue-storefront/next) Security vulnerability fix for Next.js (CVE-2025-66478).@vsf-enterprise/storefront-cli) Add --cwd flag to add-module command.@alokai/cli) Improved store composition performance by skipping excluded directories and parallelizing file copy operations.@alokai/cli) Improved error handling for missing ni commands. The CLI would throw a generic spawn nr ENOENT error when @antfu/ni was not found. It now provides a clear error message with instructions to install @antfu/ni as a dev dependency.@vsf-enterprise/module-kit) Fixed improper package.json path resolution when running the add-module command from @vsf-enterprise/storefront-cli.@alokai/connect) Updated logger printer behaviour in dev mode. Logs are now printed in a single line as a formatted message instead of JSON.@alokai/connect) Fixed ESM module loading for integrations. The middleware now prefers ESM modules and falls back to CommonJS when ESM fails, with a warning log for debugging.@alokai/connect/sdk) SDK no longer crashes with "process is not defined" error when used with browser-first bundlers like Vite.packages/tailwind-config/package.json:
diff{}[packages/tailwind-config/package.json]
"exports": {
+ "./*": "./*.css"
- ".": {
- "import": {
- "default": "./dist/index.mjs",
- "types": "./dist/index.d.mts"
- },
- "require": {
- "default": "./dist/index.cjs",
- "types": "./dist/index.d.cts"
- },
- "types": "./dist/index.d.ts"
- },
- "./nextjs": {
- "import": {
- "default": "./dist/nextjs.mjs",
- "types": "./dist/nextjs.d.mts"
- },
- "require": {
- "default": "./dist/nextjs.cjs",
- "types": "./dist/nextjs.d.cts"
- },
- "types": "./dist/nextjs.d.ts"
- },
- "./nuxt": {
- "import": {
- "default": "./dist/nuxt.mjs",
- "types": "./dist/nuxt.d.mts"
- },
- "require": {
- "default": "./dist/nuxt.cjs",
- "types": "./dist/nuxt.d.cts"
- },
- "types": "./dist/nuxt.d.ts"
- }
},
"scripts": {
"build": "unbuild"
},
"dependencies": {
- "@storefront-ui/react": "3.0.0-8cb4b8e477376e2cfbbcec1491037c76bbeba33b",
+ "@storefront-ui/react": "4.0.0",
+ "@storefront-ui/vue": "3.1.1",
- "@storefront-ui/typography": "2.6.1",
+ "@storefront-ui/typography": "3.1.0",
+ "@tailwindcss/typography": "^0.5.19",
- "tailwindcss": "3.4.4"
+ "tailwindcss": "4.1.14"
},packages/tailwind-config/src directory.packages/tailwind-config/nextjs.css and packages/tailwind-config/nuxt.css files with content:
css
@import "tailwindcss";
@import "@storefront-ui/react/tailwind-config";
@plugin "@storefront-ui/typography";Next.js only:
Create apps/storefront-unified-nextjs/app/tailwind.scss:
```diff{}[apps/storefront-unified-nextjs/app/tailwind.scss] +@import 'tailwind-config/nextjs';
+@source '..//*.ts'; +@source '..//*.tsx'; +@source '../../../../../node_modules/@storefront-ui/react'; +@source '../../../../../../node_modules/@storefront-ui/react'; ```
apps/storefront-unified-nextjs/app/[locale]/globals.scss:diff{}[apps/storefront-unified-nextjs/app/[locale]/globals.scss]
@use '@/components/cms/page';
- @tailwind base;
- @tailwind components;
- @tailwind utilities;
+ @use '../tailwind.scss';
tailwind.config.ts and your components using Tailwind upgrade guide.tailwind.config.ts.diff{}[apps/storefront-unified-nextjs/package.json]
(...)
-"@storefront-ui/react": "3.0.0-8cb4b8e477376e2cfbbcec1491037c76bbeba33b",
-"@storefront-ui/shared": "2.5.1",
+"@storefront-ui/react": "4.0.0",
+"@storefront-ui/shared": "3.1.0",
(...)
-"@storefront-ui/typography": "2.6.1",
+"@storefront-ui/typography": "3.1.0",
+"@tailwindcss/postcss": "^4.1.14",
(...)
-"tailwindcss": "3.4.4",
+"tailwindcss": "4.1.14",
apps/storefront-unified-nextjs/postcss.config.mjsdiff{}[apps/storefront-unified-nextjs/postcss.config.mjs]
(...)
plugins: {
- tailwindcss: {},
+ '@tailwindcss/postcss': {},
}
SfCheckbox component is now wrapped in a label element by default. To comply with WCAG ARIA requirements, a label must not appear inside another label. Please update all instances where SfCheckbox is used within another label, for example:diff
(...)
<label>
<SfCheckbox
(...)
+ wrapperAs="span"
/>
</label>
apps/storefront-unified-nuxt/assets/style.scss to apps/storefront-unified-nuxt/assets/css/tailwind.css and apply changes:
diff{}[apps/storefront-unified-nuxt/assets/css/tailwind.css]
- @tailwind base;
- @tailwind components;
- @tailwind utilities;
+ @import 'tailwind-config/nuxt';
+
+ @source '../**/*.vue';
+ @source '../../../../node_modules/@storefront-ui/vue';
+ @source '../../../../../node_modules/@storefront-ui/vue';tailwind.config.ts and your components using Tailwind upgrade guide.tailwind.config.ts..vue component that uses Tailwind @apply directive add a line at the top of <style> block: @reference '@/assets/css/tailwind.css';SfCheckbox component is now wrapped in a label element by default. To comply with WCAG ARIA requirements, a label must not appear inside another label. Please update all instances where SfCheckbox is used within another label, for example:
diff
(...)
<label>
<SfCheckbox
(...)
+ wrapper-tag="span"
/>
</label>diff{}[apps/storefront-unified-nextjs/package.json]
-"@vue-storefront/next": "6.1.0",
+"@vue-storefront/next": "7.0.0",
-"next": "14.2.25",
+"next": "16.1.1",
-"next-intl": "3.26.3",
+"next-intl": "4.6.0",
-"next-runtime-env": "3.3.0",
-"react": "18.3.1",
-"react-dom": "18.3.1",
+"react": "19.2.3",
+"react-dom": "19.2.3",
-"@types/react": "18.3.2",
+"@types/react": "19.2.7",
-"@types/react-dom": "18.3.0",
+"@types/react-dom": "19.2.3"
apps/storefront-unified-nextjs/next.config.mjs. Move outputFileTracingRoot and typedRoutes from experimental to top-level config:diff{}[apps/storefront-unified-nextjs/next.config.mjs]
output: 'standalone',
+ outputFileTracingRoot: join(fileURLToPath(import.meta.url), '..', '..', '..', '..'),
sassOptions: {
+ typedRoutes: true,
typescript: {
- experimental: {
- outputFileTracingRoot: join(fileURLToPath(import.meta.url), '..', '..', '..', '..'),
- typedRoutes: true,
- },
params and searchParams APIs are now asynchronous. Update all usages accordingly, as shown below:diff
- const { params, searchParams } = props;
+ const { locale: appLocale } = await props.params;
- const { locale: appLocale } = params;
+ const searchParams = await props.searchParams;
Make sure to update the typings for page props, as shown in the example:
diff
interface CategoryPageProps extends PropsWithCmsPage<CategoryPage> {
- params: {
+ params: Promise<{
locale: string;
slugs?: string[];
- };
+ }>;
- searchParams: SearchParams;
+ searchParams: Promise<SearchParams>;
}
next-intl config migration. Routing should be specified according to the new way:```ts{}[apps/storefront-unified-nextjs/i18n.ts]
import { notFound } from 'next/navigation';
import type { LocalePrefix, LocalePrefixMode } from 'next-intl/routing'; // [!code ++]
import { getRequestConfig } from 'next-intl/server';
// ...
export const locales = ['en', 'de']; // [!code --]
export const locales = ['en', 'de'] as const; // [!code ++]
export const defaultLocale = 'en';
export const localePrefix: 'always' | 'as-needed' | 'never' = 'as-needed'; // [!code --]
export const localePrefix: LocalePrefix
export default getRequestConfig(async ({ locale }) => { // [!code --]
export default getRequestConfig(async ({ requestLocale }) => { // [!code ++]
let locale = await requestLocale; // [!code ++]
if (!locale) locale = defaultLocale; // [!code ++]
// Validate that the incoming locale parameter is valid
if (!locales.includes(locale)) notFound(); // [!code --]
if (!locales.includes(locale as (typeof locales)[number])) notFound(); // [!code ++]
return {
locale, // [!code ++]
messages: (await import(`./lang/${locale}`)).default(),
timeZone,
};
```
```ts{}[apps/storefront-unified-nextjs/config/navigation.ts] import { createLocalizedPathnamesNavigation } from 'next-intl/navigation'; // [!code --] import { createNavigation } from 'next-intl/navigation'; // [!code ++] import type { Pathnames } from 'next-intl/routing'; // [!code --] import { defineRouting, type LocalePrefixMode, type Pathnames } from 'next-intl/routing'; // [!code ++] import type { ComponentProps } from 'react';
import { localePrefix, locales } from '@/i18n'; // [!code --] import { defaultLocale, localePrefix, locales } from '@/i18n'; // [!code ++]
export const pathnames = {
// ...
} satisfies Pathnames
export const { Link, redirect, usePathname, useRouter } = createLocalizedPathnamesNavigation({ // [!code --] const routing = defineRouting<typeof locales, LocalePrefixMode, Record<{} & string, string> & typeof pathnames>({ // [!code ++] defaultLocale, // [!code ++] localePrefix, locales, pathnames: pathnames as Record<{} & string, string> & typeof pathnames, // [!code --] pathnames, // [!code ++] }); ```
next-intl now requires you to specify the locale when performing a redirect. Update your code as shown below:+ const locale = await getLocale();
redirect({
- pathname: `/${redirectPath}`,
- query: { cmsTicketId },
+ href: { pathname: `/${redirectPath}`, query: { cmsTicketId } },
+ locale,
});
headers into middlewareModule — they must now return a Promise:defineSdkModule(({ buildModule, middlewareModule }) =>
buildModule(middlewareModule<Endpoints>, {
/* ... */
defaultRequestConfig: {
getConfigSwitcherHeader,
- headers: () => ({ 'my-header': 'value' }),
+ headers: () => Promise.resolve({ 'my-header': 'value' }),
},
}),
);
Note: If you use
getRequestHeadersmethod coming frombuildModuleyou do not have to do anything.
For further information on upgrading React and Next.js, follow the official upgrade guides:
Update your package.json:
```diff{}[package.json] -"nuxt": "^3.13.2", +"nuxt": "^4.0.0", -"nuxt-jsonld": "^2.0.8", -"@nuxtjs/i18n": "^8.5.6", +"@nuxtjs/i18n": "^10.2.3", -"@pinia/nuxt": "^0.5.5", +"@pinia/nuxt": "^0.11.0", -"pinia": "^2.2.6", +"pinia": "^3.0.4",
2. Remove `nuxt-jsonld` module
`nuxt-jsonld` is not compatible with Nuxt 4. Replace `useJsonld` with native `useHead`:
```diff{}[nuxt.config.ts]
modules: [
- 'nuxt-jsonld',...
]
```diff{}[composables/seo/useSeoProduct.ts] -import { useJsonld } from '#jsonld'; -useJsonld({ ... }); +useHead({ + script: [ + { + type: 'application/ld+json', + innerHTML: JSON.stringify({ ... }), + }, + ], +});
3. Migrate i18n to v10 directory structure
i18n v10 enforces a new [directory structure](https://i18n.nuxtjs.org/docs/guide/migrating) where all i18n files must be placed under a root-level `i18n/` directory. Move locale files accordingly:
```bash
mkdir -p i18n
mv lang i18n/lang
mv i18n.config.ts i18n/i18n.config.ts
Update imports in locale index files:
```diff{}[i18n/lang/en/index.ts] -import base from '@/lang/en/base.json'; +import base from '@/i18n/lang/en/base.json';
4. Rename `@alokai/instrumentation-nuxt3-module` to `@alokai/instrumentation-nuxt-module`
```diff{}[package.json]
-"@alokai/instrumentation-nuxt3-module": "...",
+"@alokai/instrumentation-nuxt-module": "...",
```diff{}[nuxt.config.ts] modules: [ - '@alokai/instrumentation-nuxt3-module',... + '@alokai/instrumentation-nuxt-module',... ]
5. Update `@nuxt/image` custom providers to v2 API
Custom image providers must use `defineProvider` from `@nuxt/image/runtime`:
```diff{}[modules/alokai-cloudinary/provider.ts]
-import { getImage as cloudinaryGetImage } from '#image/providers/cloudinary';
-import type { ProviderGetImage } from '@nuxt/image';
+import { defineProvider } from '@nuxt/image/runtime';
+import cloudinaryFactory from '@nuxt/image/runtime/providers/cloudinary';
-export const getImage: ProviderGetImage = (src, options, ctx) => {
+export default defineProvider({
+ getImage: (src, options, ctx) => {
// ...
- return cloudinaryGetImage(src, { ...options, baseURL }, ctx);
-};
+ const cloudinary = cloudinaryFactory();
+ return cloudinary.getImage(src, { ...options, baseURL }, ctx);
+ },
+});
useVModel with native computedVueUse's useVModel returns a Ref type incompatible with Vue 3.5's v-model:
-import { useVModel } from '@vueuse/core';
-const internalModelValue = useVModel(props, 'modelValue', emit);
+const internalModelValue = computed({
+ get: () => props.modelValue,
+ set: (value) => emit('update:modelValue', value),
+});
To migrate your storefront-middleware app to ESM, follow these steps:
apps/storefront-middleware/package.json:diff{}[apps/storefront-middleware/package.json]
{
"name": "storefront-middleware",
"private": true,
"version": "x.x.x",
+ "type": "module",
"main": "./src/index.ts",
"license": "MIT",
"scripts": {
- "build": "NODE_OPTIONS=\"--max-old-space-size=8192\" tspc",
+ "build": "NODE_OPTIONS=\"--max-old-space-size=8192\" tspc && tsc-alias --resolve-full-paths",
"start": "node lib/src/index.js",
- "dev": "tspc && concurrently --raw \"tspc --preserveWatchOutput --watch\" \"tsx watch --clear-screen=false src/index.ts\"",
+ "dev": "tsx watch --clear-screen=false src/index.ts",
...
},
"devDependencies": {
...
+ "tsc-alias": "^1.8.16",
...
}
}
apps/storefront-middleware/tsconfig.json:diff{}[apps/storefront-middleware/tsconfig.json]
{
"compilerOptions": {
...
- "module": "Node16",
- "moduleResolution": "Node16",
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "baseUrl": ".",
"rootDir": ".",
"outDir": "lib",
...
}
}
bash
yarn install
```diff - const { something } = require('./module'); + import { something } from './module';
Update any dynamic imports to use ESM syntax if needed.
For Nuxt storefronts, ensure typescript.typeCheck: 'build' is set in nuxt.config.ts:
ts{}[nuxt.config.ts]
export default defineNuxtConfig({
typescript: {
typeCheck: 'build',
},
});
Migration of SAP-ASM module (follow only if you're using it)
Update typing in apps/storefront-middleware/sf-modules/sap-asm/middleware/api/searchCustomer360.ts:
-import type { Customer360List } from '@vsf-enterprise/sap-commerce-assisted-service-module-webservices-sdk';
import type { SapccIntegrationContext } from '@vsf-enterprise/sapcc-api';
-import type { SearchCustomer360Props } from '@vsf-enterprise/sapcc-types';
+import type { Asm, SearchCustomer360Props } from '@vsf-enterprise/sapcc-types';
import { getTypedApiClient } from '@/integrations/typedApiClient';
export const searchCustomer360 = async (
context: SapccIntegrationContext,
args: SearchCustomer360Props,
-): Promise<Customer360List> => {
+): Promise<Asm.Customer360List> => {
/* ... */
If you are using Contentstack CMS, update your code to use snake_case field names:
// Dynamic pages
- page.componentsAboveFold
+ page.components_above_fold
- page.componentsBelowFold
+ page.components_below_fold
// Category pages
- page.componentsTop
+ page.components_top
- page.componentsBottom
+ page.components_bottom
// Product pages
- page.componentsBottom
+ page.components_bottom
Component props from CMS content now use snake_case:
// Hero component
- backgroundImage={data.backgroundImage}
+ backgroundImage={data.background_image}
- buttonA={data.buttonA}
+ buttonA={data.button_a}
The module's wrapper components handle this mapping automatically, so if you're using the standard RenderCmsContent component, no changes are needed for component rendering.
env())If you're currently using next-runtime-env, follow these steps:
Replace next-runtime-env imports with @vue-storefront/next:
- import { env } from "next-runtime-env";
+ import { env } from "@vue-storefront/next";
Files to update:
sdk/options.tsconfig/image-loaders/cloudinary/cloudinary.tsnext-runtime-envnext.config.mjsIf you're using env() in your next.config.mjs, add the import:
+ import { env } from "@vue-storefront/next";
import { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } from 'next/constants.js';
const nextConfig = {
images: env('NEXT_PUBLIC_IMAGE_LOADER_FETCH_URL') ? cloudinaryConfig : defaultImageConfig,
};
useEnvContext and PublicEnvScriptRemove any usage of useEnvContext() hook:
- import { useEnvContext } from "next-runtime-env";
+ import { env } from "@vue-storefront/next";
export function MyComponent() {
- const env = useEnvContext();
- const apiUrl = env.NEXT_PUBLIC_API_URL;
+ const apiUrl = env("NEXT_PUBLIC_API_URL");
}
Remove <PublicEnvScript /> from your layout:
- import { PublicEnvScript } from "next-runtime-env";
export default function RootLayout({ children }) {
return (
<html>
<head>
- <PublicEnvScript />
</head>
</html>
);
}
next-runtime-env package from apps/storefront-unified-nextjs/package.jsonMirrored from our private GitHub release registry (@alokai/ecosystem); release dates are the corresponding tag dates. We proactively surface security updates and releases of special interest to you — individual package changelogs carry per-package detail.