Connecting a chosen CMS to a frontend that already exists
The CMS is chosen and the frontend is built. What is missing is the contract between them — and the parts of it that nobody specifies, which are preview, invalidation and what happens when one side is unavailable.
The API works and the integration does not
Fetching content from a headless CMS is a day's work. What makes an integration usable is everything around it: how an editor sees a draft, how a publish reaches a cache that is already serving the old page, how a content model change is absorbed by a frontend built against the previous one, and what the site does when the CMS is slow or unavailable. Those are the parts that are not in the CMS's documentation, because they belong to the boundary rather than to either side.
- The frontend fetches content and editors cannot preview a draft
- Publishing does not appear on the site for an unpredictable period
- A content model change breaks the frontend and nobody knows what depends on it
- The site is slow because each page assembles itself from many API calls
- The CMS being unavailable takes the whole site down rather than degrading it
- Nobody can say which frontend components depend on which content fields
- Content types have to be added and each one is a frontend release
- The integration works and its failure behaviour has never been examined
The people who usually bring us this problem
A team with a CMS and a frontend that do not quite meet
Both exist and the boundary between them is where the problems are.
A team whose editors cannot preview
The CMS is headless and the editorial workflow has not caught up with that.
A team adding content types regularly
Each addition is a frontend release and the coupling is the constraint.
What this costs while it goes unfixed
Engineering faults are rarely confined to the engineering layer. These are the commercial consequences we see most often.
Preview is the requirement that shapes the integration
A headless CMS shows content as fields; the frontend renders it. An editor seeing their draft requires an authenticated path from the CMS to the frontend that renders unpublished content — and whether that is built determines how much of the editorial workflow is usable. It is the first thing to establish and the most expensive to retrofit.
Publishing has to reach a cache that is already answering
The frontend serves cached pages, so a publish changes the CMS and not the site. Getting the change to the copies already served requires either a short lifetime, which means load, or an invalidation path from the CMS to the frontend's cache — which requires the CMS to express what changed and the frontend to understand it.
The content model and the frontend are coupled whether or not that is acknowledged
Every component reads fields, and a field changing shape breaks the components that read it. Without a recorded mapping from fields to components, a model change is a frontend investigation — and adding a content type becomes a release rather than a configuration.
The CMS is a dependency and the site behaves as though it is not
A frontend that fetches on every request is as available as the CMS behind it. Caching, fallbacks and a defined behaviour when the CMS is slow or down are what separate a site that degrades from one that goes dark — and they are designed rather than inherited.
Capabilities
Each of these is work we carry out, not an area we advise on.
The contract between the two sides
What the frontend requires from the API per content type, and what the CMS actually exposes — with the gaps named. The contract is the integration's specification, and writing it down is what makes a later model change a decision rather than an incident.
Field-to-component mapping
Which frontend components depend on which content fields, recorded. It is the document that makes a model change safe, and it is what allows a content type to be added without a frontend release where the existing components already cover it.
Preview and draft handling
An authenticated path from the CMS to the frontend that renders unpublished content, including where a page is composed from several content types. Built deliberately, because it does not exist by default and it is the requirement that most constrains the design.
Cache invalidation from the CMS
Making a publish reach the copies already served: what the CMS can express about a change, how the frontend receives it, and what the fallback is where the CMS cannot express it precisely. This is the difference between a site that reflects publishing and one that appears not to.
Query shape and request count
How many API calls a page needs to render, and whether that can be reduced. A page assembling itself from twenty requests is slow, fragile and expensive against a CMS that meters API usage — and the fix is usually a different query shape rather than caching.
Failure behaviour
What the site does when the CMS is unavailable, slow, or returns something unexpected — serve stale, serve a fallback, or degrade a section. Defined rather than inherited, because a frontend that fetches on every request has the CMS's availability as its own.
Editorial workflow
How content moves from draft to published with the frontend in place: review, scheduling, correction after publication, and what an editor can change without a developer. The workflow is what determines whether the integration is experienced as working.
Change management for the model
How a content model change is made safely: what depends on the field being changed, what has to be released alongside it, and what the order is. The alternative is that models stop changing, which is how a CMS becomes the constraint it was chosen to remove.
Engineering methodology
The sequence is deliberate. The order is usually what determines whether the work holds or has to be repeated.
Establish the preview requirement first
Before any architecture, because it is the constraint that shapes the rest and the most expensive to retrofit. What an editor has to be able to see, and where, decides how the frontend has to be reachable from the CMS.
Write the contract down
What the frontend requires per content type and what the CMS provides, with the gaps named. It is the specification the integration is built against and the document that makes a later change reviewable rather than investigative.
Record the field-to-component mapping
As the integration is built, not afterwards. It is what makes a model change safe and it is the reason a new content type can sometimes be added without touching the frontend — which is a property worth having deliberately.
Treat invalidation as a path, not a setting
The CMS has to express what changed and the frontend has to understand it. Where the CMS cannot be precise, the fallback is chosen deliberately — a shorter lifetime, a broader invalidation, or an accepted delay — with its cost stated rather than absorbed silently.
Define the failure behaviour
What a visitor sees when the CMS is unavailable, slow or wrong, and whether the site degrades or stops. Serving a stale page is usually better than serving nothing, and that is a decision rather than an accident of how the fetch was written.
Reduce the request count before caching it
A page making twenty calls is a query-shape problem and caching it hides the problem rather than solving it. The count is measured and reduced first, because caching a badly shaped page produces a slow cache and a fragile one.
What an engagement produces
Documentation is a deliverable, not an afterthought. On most of these engagements a large part of the value is a defect report precise enough for another team to act on.
Contract
- What the frontend requires per content type, and what the CMS exposes
- The gaps between them, named, with how each is handled
- Field-to-component mapping, recorded
- Preview and draft handling design
- Cache invalidation path, and the fallback where precision is not available
Integration
- Content fetching, with the request count per page measured and reduced
- Authenticated preview path from CMS to frontend
- Cache invalidation wired to publish
- Failure behaviour implemented: serve stale, fallback, or degrade
- Editorial workflow supported end to end
Handover
- The contract and the mapping, as maintained documents
- How to add a content type, and when it needs a frontend release
- What to change to alter a cache lifetime or an invalidation path
- What the site does when the CMS is unavailable, and how long that is tolerable
- What the integration does not cover, stated plainly
Architecture and technology
What sits at the boundary
- The API contract: what is requested, what is returned, in what shape
- Authentication for content reads, and separately for preview
- The preview path, which is a different and more privileged route
- Cache lifetimes and the invalidation that reaches them
- The query shape, and how many requests a page needs
- The failure behaviour when the CMS is unavailable or wrong
- The field-to-component mapping, and who updates it
What an integration is usually missing
- A preview path, so editors cannot see a draft
- Invalidation, so publishing does not reach the site promptly
- A recorded mapping, so a model change is an investigation
- A defined failure behaviour, so the CMS's availability is the site's
- A reduced query shape, so caching is compensating for a design problem
- A documented way to add a content type
If this is not quite your problem
These overlap at the edges. Sending you to the right page is more useful than having you work it out.
The content still has to be migrated
Modelling, mapping and moving content into the CMS.
Headless CMS migrationThe architecture is still being decided
Choosing and designing the decoupled stack itself.
Headless website developmentThe frontend needs engineering
Routing, rendering modes and data fetching in the application.
Next.js developmentThe CMS is WordPress
Keeping WordPress for editors and replacing the rendering layer.
Headless WordPress developmentFrequently asked
Do you have an integration example?
No. Our published engagements are platform and infrastructure work, and none of them is a headless CMS integration a reader could inspect. What this page describes is the boundary — preview, invalidation, the field-to-component mapping and the failure behaviour — which is where integrations actually fail and which is checkable without a reference. If an example is a requirement, that is reasonable and this is not the page that has one.
How do editors preview content?
Through an authenticated path from the CMS to the frontend that renders unpublished content — which has to be built, because it does not exist by default. A headless CMS shows content as fields and the frontend renders it, so preview requires the frontend to be reachable from the CMS with enough privilege to read a draft, and for it to render the same composition a visitor would see. It is the requirement that most constrains the design, so it is established first rather than retrofitted.
Why does publishing not show up on the site?
Because the frontend is serving cached pages and the publish changed the CMS. Getting the change to the copies already served needs either a short lifetime, which costs origin load, or an invalidation path from the CMS to the frontend's cache — which needs the CMS to express what changed and the frontend to understand it. Where the CMS cannot be precise about that, the fallback is chosen deliberately and its cost stated, rather than left to whatever the cache happens to do.
What happens if the CMS goes down?
Whatever the integration was designed to do, which is why it is specified rather than inherited. A frontend that fetches on every request is only as available as the CMS behind it, so the options are to serve a stale cached page, to serve a fallback, or to degrade a section — and serving something stale is usually better than serving nothing. That is a decision made during the build, along with how long a stale page is acceptable before the site should stop claiming to be current.
Can we add content types without a frontend release?
Sometimes, and it depends on whether the existing components already cover what the new type needs. That is exactly what the field-to-component mapping establishes: if a new type's fields map onto components that already exist, it can be configured in the CMS and rendered without a release. If it needs a component that does not exist, that is frontend work — and knowing which case you are in before starting is the difference between a model that grows and one that stops changing because every addition is a project.
Related capabilities and work
Bring us the problem you have not been able to fix
Describe what is happening rather than what you think the cause is. If we are not the right people for it, we will say so.