Readme · Guides · Reference · Contributing
The Optimization SDK Suite is pre-release (alpha). Breaking changes can be published at any time.
This is a reference implementation using both the Optimization Node SDK and Optimization Web SDK, and is part of the Contentful Optimization SDK Suite.
Use this implementation when you need a hybrid SSR/browser example. It demonstrates a stateless Node SDK server flow, a stateful Web SDK browser flow, consent-aware cookie-based profile continuity between them, and local mock API usage for end-to-end validation.
On the server side, the stateless Node SDK is created once at module load. Each request binds
request-scoped options with sdk.forRequest(...), then calls stateless event methods on the
returned request object. The demo stores application-owned consent in a server-readable cookie and
writes the shared anonymous ID cookie only when consent permits profile continuity. When app consent
is missing or denied, the server clears the shared anonymous ID cookie, skips Node SDK event calls,
and lets the browser render baseline entries.
The goal of this reference implementation is to illustrate the usage of cookie-based communication in both the Node and Web SDKs, which is an important component of many server-side/client-side hybrid SSR and ESR solutions.
This hybrid architecture allows more cache flexibility when personalization is deferred to browser code. If the server embeds personalized output or profile-derived values, treat that response as personalized and avoid shared caching unless you vary on all relevant inputs.
The server and browser share one APP_LOCALE. Server code passes it to the Node SDK request context
with sdk.forRequest({ locale: APP_LOCALE }) and uses it when building event context. Browser code
passes the same value as the Web SDK top-level locale and directly to Contentful CDA entry
fetches. Do not use contentful.js withAllLocales or raw CDA locale=* for entries passed to SDK
resolution; the resolver expects direct single-locale fields such as fields.nt_experiences and
fields.nt_variants. See
Locale handling in the Optimization SDK Suite
for the broader locale model and
Entry personalization and variant resolution
for the entry contract.
.nvmrc)Run all steps from the monorepo root.
Install pnpm packages:
pnpm install
Build the local package tarballs consumed by implementations:
pnpm build:pkgs
Install this implementation so its local @contentful/* dependencies resolve from pkgs/:
pnpm implementation:run -- node-sdk+web-sdk implementation:install
Create the local .env file if it does not already exist:
test -f implementations/node-sdk+web-sdk/.env || cp implementations/node-sdk+web-sdk/.env.example implementations/node-sdk+web-sdk/.env
The .env.example values are valid only against the mock server implementation. To test the
implementation against a live server environment, see the
mocks package for information on how to set up Contentful space with
test data.
Run these commands from the monorepo root.
Start servers:
pnpm implementation:run -- node-sdk+web-sdk serve
Stop servers:
pnpm implementation:run -- node-sdk+web-sdk serve:stop
Run E2E:
pnpm test:e2e:node-sdk+web-sdk
The application can be accessed via Web browser at http://localhost:3000. See
implementations/node-sdk+web-sdk/package.json for lower-level local commands.
E2E tests are run using Playwright.
Install implementation dependencies, browser binaries, and system dependencies:
pnpm setup:e2e:node-sdk+web-sdk
Run the E2E test suite:
pnpm test:e2e:node-sdk+web-sdk
The tests can alternatively be run using Playwright's GUI:
pnpm implementation:run -- node-sdk+web-sdk test:e2e:ui