Frontend
The Evolve storefront is a Next.js 15 application using the App Router, React 19, Tailwind CSS 4, and TypeScript. It is designed for fast anonymous page loads through aggressive CDN caching while providing full server-side rendering for authenticated sessions.
Rendering strategy
| Visitor type | Behaviour |
|---|---|
| Anonymous | CDN cache: s-maxage=900; stale-while-revalidate=2592000 (15 min fresh, 30 days stale) |
| Authenticated | SSR on every request (no CDN cache) |
The next.config.ts conditionally sets the Cache-Control header
based on the absence of userToken and userData cookies, so
returning customers always see fresh data.
Internationalization
Routing is handled by next-intl with the always prefix strategy,
so every URL starts with a locale segment. Eight locales are supported:
| Locale | URL prefix |
|---|---|
nl-NL | /nl |
en-GB | /en |
de-DE | /de |
fr-FR | /fr |
es-ES | /es |
it-IT | /it |
nl-BE | /be/nl |
fr-BE | /be/fr |
Pathnames are localized per language (e.g. /nl/winkelwagen,
/de/warenkorb, /en/cart). The mapping is defined in
packages/site-config/src/i18n/config.ts.
Rewrites
The root /:locale path and catch-all fallback both rewrite to
/content/* routes, letting the CMS handle homepage and content pages
without a separate routing layer. This is configured in
next-rewrites.ts.
CMS abstraction
The EVOLVE_CMS environment variable ("contentful" or
"storyblok") controls which preview provider and data-attribute
helper is active. This allows the same codebase to work with either
CMS without build-time branching. Preview API routes are mounted at
/api/preview (Storyblok) and /api/preview-contentful
(Contentful).
Image optimization
A custom image loader (src/lib/image-loader.ts) detects the CDN
origin from the image URL and applies the correct transform syntax:
| Source | Transform example |
|---|---|
| Storyblok | /m/{width}x0/filters:quality(80) |
| Amplience | &w={width} |
| Contentful | ?w={width}&fm=webp&q=80 |
| Lab Digital DAM | ?format=auto&width={width} |
| Bluestone PIM | ?format=auto&width={width} |
Deployment
The application builds with output: "standalone" for containerized
deployments without node_modules. The build ID is set from
SERVICE_VERSION for deterministic cache busting.
A Sentry tunnel at /api/capture-errors proxies browser error reports
through the application's own domain to avoid ad-blocker interference.
See Observability for the full error
tracking setup.
📄️ UI component library
The two-tier UI component library: base primitives and commerce components, with CVA variants and Radix accessibility.
📄️ Next.js middleware
The Next.js middleware chain: token refresh, B2B routing, i18n, and security headers.