Zalando — More Editorial Content, please.¶
Summary¶
George Tagkalidis and Daniel Strecker (Zalando Engineering, Zalando Marketing Services + Sustainability teams) describe the Landing Pages stack that replaced Zalando's legacy editorial-tooling system. The new stack is built on Contentful as a headless CMS, integrated into Zalando's then-new Interface Framework platform rather than the phased-out Project Mosaic architecture. Two architectural primitives carry most of the load: a custom Contentful proxy data service that sits between Zalando's Fashion Store API (FSA) GraphQL aggregator and Contentful, mapping Contentful entries into GraphQL types and adding a caching + resilience layer so FSA only calls Zalando-operated endpoints; and a content aggregator that pulls in data from other Zalando services (e.g. sustainability-certificate details from the same service that feeds the Product Detail Page) so that a certificate list rendered on a landing page and one rendered on a PDP share a single source of truth. The post's second half walks through the Sustainability Certificate module — an entry-type contributed by the Sustainability team, not by the original ZMS landing-pages team — as a concrete demonstration that the platform is extensible via inner sourcing: new content formats require touching Contentful (new data model), the Contentful proxy (new GraphQL mapping), and Rendering Engine UI components, and nothing else. Quantified impact: landing- page time-to-go-live 2 days → 4 hours, a previously-required 2-week lead time removed entirely, non-technical stakeholders own the end-to-end create/upload/publish flow, and 82% YoY increase in published landing pages since rollout.
The post is Zalando's canonical wiki source on the content- management-as-platform altitude — the axis where the artefact that ships is not a service but an editorial workflow whose day-to-day operators are copywriters and brand managers rather than engineers. It sits at the intersection of three existing Zalando wiki axes: Interface Framework as the runtime substrate (axis 7 on companies/zalando); UBFF + FSA as the data aggregation substrate (axis 6); and build-vs-buy for CMS as a new architectural stance — Zalando explicitly considered building a CMS from scratch and rejected it on limitless- scope grounds, choosing an external headless-CMS SaaS wrapped in an internal proxy instead.
Key takeaways¶
-
Headless CMS as the editorial substrate, not the delivery runtime. Zalando's landing pages are content-only in Contentful; the delivery runtime is Zalando Rendering Engine. The split is architecturally load-bearing: Contentful owns the authoring UI, data model, validation, localisation (25 markets), collaboration, and content-change workflow; Zalando owns the presentation and is therefore immune to Contentful's frontend capabilities becoming a limiting factor over time. This is the canonical wiki instance of patterns/headless-cms-for-editorial-content (Source: sources/2022-09-28-zalando-more-editorial-content-please).
-
Explicit build-vs-buy reasoning documented. The team weighed building a CMS from scratch and rejected it: "we were also conscious that trying to reinvent the wheel by building our own CMS could grow into a project with limitless scope that we would never finish." The decisive property driving the buy decision was extensibility of the CMS UI via custom apps, in combination with out-of-the-box multi-language support and collaboration features — capabilities that scale in scope with the product roadmap and would be expensive to rebuild from scratch. Canonical wiki example of platform-engineering teams making a build-vs-buy choice based on scope risk rather than feature gaps.
-
Contentful proxy as an isolation layer between a third-party SaaS and the internal API platform. The proxy sits between FSA and Contentful and performs three jobs: (a) mapping Contentful's JSON entry schema into FSA's GraphQL types; (b) caching Contentful responses so every landing-page request does not hit an external API; (c) resilience — "the aggregation layer calls directly only Zalando-operated APIs" so that a Contentful outage degrades gracefully against the proxy's cache rather than cascading through FSA. Canonical wiki instance of patterns/proxy-layer-for-external-saas; the pattern generalises to any architecture where an internal API platform must integrate a best-of-breed external service without letting that service become a direct runtime dependency of the aggregation tier.
-
Drag-and-drop module composition inside Contentful is the editorial primitive. A landing page is one top-level entry (title, URL path, SEO metadata) that references a list of module entries (banner, text block, product carousel, certificate list, etc.), each with its own Contentful schema and validation. Content Managers build pages via a drag-and-drop UI that rearranges the module list; rearranging layout preserves module content (unlike the legacy tool where layout changes reset content). Canonical instance of concepts/cms-entry-type-modular-composition and patterns/drag-and-drop-cms-layout.
-
Cross-surface content unification via the FSA-side enrichment aggregator. The Sustainability Certificate module stores only certificate IDs in Contentful — the logo URL, title, and description come from the same Zalando service that already feeds these fields to the Product Detail Page's sustainability accordion. At FSA resolution time, the Contentful proxy's response is enriched via a content aggregator service; both consumers see the same
SustainabilityCertificateGraphQL type with identical values. This is the canonical wiki instance of concepts/cross-surface-content-unification and patterns/cross-surface-enrichment-via-internal-service: authoring-time data (the which certificates to show) lives in the CMS; runtime-evolving data (the what each certificate says) lives in the system of record. Quote: "This ensures that the certificate detail information on Landing Pages and on the Product Detail Pages are always in sync." -
Inner sourcing as the extensibility mechanism, validated by a second team's contribution. The Sustainability team — not the original ZMS landing-pages team — designed and landed the Sustainability Certificate module as a self-contained change touching exactly three layers: (a) a new Contentful entry-type, (b) a new Contentful-proxy mapping to an existing FSA GraphQL type (
Collection.entities), (c) new UI components on web + app. No existing layer had to change. The post cites O'Reilly's Adopting Innersource as the framing and positions this contribution as proof that the "streamlined contribution model" goal of the original requirements was met. Canonical wiki instance of patterns/inner-sourced-module-extension. -
Content-Ops outcomes are the real metric, not per-service latency. The post's business-impact numbers are content-workflow outcomes, not system metrics: time-to-go-live 2 days → 4 hours; previously 2-week lead time removed entirely; layout changes no longer require engineering + full re-upload; single upload now covers both web + app (previously two separate flows); 82% YoY increase in landing pages published. The architectural thesis the numbers back: when the authoring workflow is the bottleneck, the winning optimisation is moving engineers out of the hot path rather than speeding up the backend. Quote: "non-technical stakeholders can complete the process end-to-end themselves."
Architecture¶
The data flow for a single landing-page request:
Web client or Zalando App
│ │
▼ ▼
[Skipper](<../systems/skipper-proxy.md>) — HTTP routing + header
│ enrichment per platform
▼
[Rendering Engine](<../systems/zalando-rendering-engine.md>)
— IF's Node.js + browser runtime
│
▼
[Fashion Store API (FSA)](<../systems/zalando-fashion-store-api.md>)
— GraphQL aggregator, consults ONLY
Zalando-operated downstreams
│
▼
[Contentful proxy](<../systems/zalando-content-proxy.md>)
— mapping + caching + resilience
│
▼
Contentful (external SaaS)
— headless CMS; landing-page entries +
referenced module entries
Two parallel paths enter the picture for enrichment:
- The Contentful proxy also calls an internal content aggregator service for CMS-referenced data that lives elsewhere in Zalando (e.g. sustainability-certificate details), so that a landing page's certificate list is populated from the same backend as the Product Detail Page's sustainability accordion.
- Rendering Engine maps each CMS module returned by FSA onto a matching Renderer (patterns/entity-to-renderer-mapping) — the same composition primitive IF uses for the rest of zalando.com.
Operational numbers¶
- Time-to-go-live: 2 days (legacy) → 4 hours (new stack) — average across page creation, content upload, and publish.
- Lead time removed: the legacy 2-week brief-to- go-live window has been removed entirely.
- Markets: 25 — Zalando operates across 25 markets, each requiring localised content; the new tool streamlines the multi-language upload flow that was "cumbersome and confusing" in the legacy system.
- Engineering involvement: previously required per page for setup; now required only when introducing a new module type (one-time cost per format).
- Parity: web + app landing pages now serve a single content source (previously two separate upload paths).
- Publication volume: +82% YoY increase in landing pages published since rollout.
Systems / concepts / patterns¶
Systems (new to wiki):
- systems/contentful — the external headless CMS SaaS.
- systems/zalando-landing-pages-stack — the umbrella name for this editorial stack (Contentful + Contentful proxy + content aggregator + FSA mapping + Rendering Engine modules).
- systems/zalando-content-proxy — the Contentful-proxy data service.
- systems/zalando-fashion-store-api — FSA, Zalando's GraphQL aggregator; first canonical wiki page. (Already referenced on many earlier Zalando source pages under the name "Fashion Store API"; this ingest promotes it to a first-class system page.)
Systems (extended with a Seen-in from this source):
- systems/zalando-rendering-engine — Renderer-mapping consumption of CMS-driven module lists.
- systems/zalando-interface-framework — landing pages as an IF-hosted surface.
- systems/zalando-graphql-ubff — FSA is the UBFF's concrete Fashion-Store instance; landing pages' module data rides on the UBFF.
- systems/zalando-mosaic — the architecture the legacy editorial tooling was built on; phased out in favour of IF.
- systems/skipper-proxy — routes landing-page requests to the Rendering Engine with per-platform header enrichment.
Concepts (new to wiki):
- concepts/headless-cms — canonical definition: CMS that separates authoring from delivery, exposing content only via API.
- concepts/cms-entry-type-modular-composition — pages as a list of module-entry references, composed via drag-and-drop.
- concepts/cross-surface-content-unification — the same reference ID produces identical rendered data across distinct product surfaces.
- concepts/build-vs-buy-for-cms — scope-risk-driven framing of the CMS build-vs-buy decision.
- concepts/inner-sourcing — the extensibility discipline Zalando frames the Sustainability team's contribution as.
- concepts/content-management-as-platform — the umbrella stance: content management is a platform capability, not a per-campaign engineering project.
Patterns (new to wiki):
- patterns/headless-cms-for-editorial-content — the architectural choice to front editorial surfaces with a headless CMS rather than hand-coded templates or a monolithic CMS.
- patterns/proxy-layer-for-external-saas — the Contentful-proxy shape: mapping + caching + resilience against a third-party dependency.
- patterns/cross-surface-enrichment-via-internal-service — CMS holds IDs; internal system of record provides values; enrichment happens at the aggregation layer.
- patterns/inner-sourced-module-extension — self- contained new content formats contributed by teams that do not own the platform.
- patterns/drag-and-drop-cms-layout — layout changes preserve content; add/remove modules without resetting the page.
- patterns/static-content-pages-via-cms-over-hand-coded-templates — the umbrella choice: move static/semi-static pages out of the codebase and into the CMS.
Caveats¶
- Code sample fidelity: the post shows a simplified
GraphQL query + JSON response for the
SustainabilityCertificateenrichment; the surrounding code (proxy mapping implementation, content aggregator implementation, UI component code) is not disclosed. - Contentful vendor-lock-in is not discussed in the post. The architectural isolation via the Contentful proxy would make a CMS migration tractable (the FSA GraphQL contract is stable; only the proxy's mapping layer would change), but there is no mention of alternative CMSes being kept warm.
- Cache-invalidation strategy in the Contentful proxy is not disclosed — neither TTLs nor invalidation signalling (Contentful webhooks, etc.) are named.
- Cost of Contentful at Zalando scale (25 markets, 82% YoY page growth) is not disclosed.
- The content aggregator service is undersanded — the post names its existence and role (pull cross-system data for inclusion in Contentful-sourced responses) but does not disclose its implementation shape.
- Analytics / experimentation integration for landing pages (A/B testing via Octopus, for example) is not mentioned; integrations with Zalando's platform-wide cross-cutting concerns are implicit.
Source¶
- Original: https://engineering.zalando.com/posts/2022/09/editorial-content.html
- Raw markdown:
raw/zalando/2022-09-28-more-editorial-content-please-9081d02c.md
Related¶
- systems/contentful · systems/zalando-landing-pages-stack · systems/zalando-content-proxy · systems/zalando-fashion-store-api · systems/zalando-rendering-engine · systems/zalando-interface-framework · systems/zalando-graphql-ubff · systems/zalando-mosaic · systems/skipper-proxy
- concepts/headless-cms · concepts/cms-entry-type-modular-composition · concepts/cross-surface-content-unification · concepts/build-vs-buy-for-cms · concepts/inner-sourcing · concepts/content-management-as-platform
- patterns/headless-cms-for-editorial-content · patterns/proxy-layer-for-external-saas · patterns/cross-surface-enrichment-via-internal-service · patterns/inner-sourced-module-extension · patterns/drag-and-drop-cms-layout · patterns/static-content-pages-via-cms-over-hand-coded-templates
- companies/zalando