Building a Headless CMS‑Powered Site with Next.js

Hero image for Building a Headless CMS‑Powered Site with Next.js. Image by Héctor J. Rivas.
Hero image for 'Building a Headless CMS‑Powered Site with Next.js.' Image by Héctor J. Rivas.

A headless CMS and Next.js make a natural pairing. The CMS gives editors a structured place to manage content, whilst Next.js gives us control over rendering, performance, routing, and frontend architecture.

That separation is the main point. We're no longer tying editorial workflow to page templates in the classic monolithic CMS sense. Instead, we model content once and decide how to present it across routes, devices, and features in code.

That same separation was a major part of the Nando’s replatform, where a headless Next.js front end sat on top of Storyblok so editorial concerns could move independently from routing, rendering, and platform behaviour.


Start with the Content Model, Not the Page

One of the most common mistakes in headless projects is modelling content around a single current design. That works for a few weeks, then becomes restrictive as soon as the site grows.

It's usually better to model reusable concepts instead:

  • article
  • author
  • category
  • hero image
  • call to action

This gives us a content layer that is easier to scale, easier to query, and easier to reuse across different page types. It also means the front end can map welldefined entries into welldefined view models instead of wrestling raw CMS responses in every page file.


Build a Small Fetching Layer

We should avoid scattering raw CMS queries across page files. A thin content client keeps concerns separate and improves testability:

type Article = {  slug: string;  title: string;  excerpt: string;};export const getArticleBySlug = async (  slug: string): Promise<Article | null> => {  const response = await fetch(`${process.env.CMS_URL}/articles/${slug}`, {    headers: {      Authorization: `Bearer ${process.env.CMS_TOKEN ?? ''}`,    },    next: { revalidate: 300 },  });  if (!response.ok) {    return null;  }  return (await response.json()) as Article;};

This kind of wrapper gives us a stable boundary. If the CMS changes shape later, we update the content layer rather than every route in the application.


Map Raw Content into Front‑End Shapes

CMS responses are rarely the same shape our components actually want. We should resist the temptation to pass raw payloads straight into the UI.

An explicit mapping layer keeps our components smaller, keeps rendering logic focused, and makes future migrations far less painful. It also helps when multiple CMS entry types eventually need to feed the same component.


Use the Right Rendering Strategy

Headless CMS sites often benefit from static generation or ISR because most content changes are editorial rather than userdriven. That gives us fast delivery without rebuilding the whole application for every small update.

If the CMS supports webhooks, ondemand revalidation is even better. We can refresh affected pages when content is published, which aligns the delivery model with the editorial workflow.


Preview and Draft Content Matter

Editors rarely want to publish blind. A solid preview flow is part of a productionready headless setup, not a nice extra.

That usually means three things:

  • a secure preview entry point
  • draftaware data fetching
  • clear separation between published and preview tokens

Without that separation, preview logic tends to leak into production data paths, which quickly becomes risky.


Think About Maintainability Early

Keep Components Presentation‑Focused

Components should render data, not understand CMS plumbing. That makes them easier to test and easier to reuse.

Version Content Contracts Carefully

Once editors depend on a content type, changing it casually can break pages unexpectedly. A little schema discipline goes a long way.

Plan for Scale

Pagination, image optimisation, taxonomy pages, and search are usually not far behind the first launch. The earlier we acknowledge that, the better our architecture tends to hold up.


For the frameworkspecific details behind these patterns, the official documentation below is the best place to go deeper:


Wrapping up

A good headless CMS setup in Next.js is less about wiring one API call and more about drawing clean boundaries between content, data fetching, and presentation. When we model content carefully, centralise CMS access, and choose rendering strategies that reflect editorial behaviour, we get a site that is faster to evolve and much easier to keep healthy over time.

Key Takeaways

  • Model reusable content concepts instead of mirroring one page design.
  • Keep CMS access behind a small typed content layer.
  • Treat preview, revalidation, and schema discipline as core concerns.

Once those pieces are in place, a headless CMS stops being just a content source and becomes a reliable foundation for scalable frontend development.


Categories:

  1. CMS
  2. Contentful
  3. Development
  4. Front‑End Development
  5. Guides
  6. Next.js