Frontend
The Evolve storefront is a Next.js 16 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
Section titled “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
Section titled “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
Section titled “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
Section titled “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
Section titled “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
Section titled “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.

