Structuring content in a Headless CMS: a Practical guide

Flotiq team
Flotiq team8 min read19 Dec 2024

Effective data management and storage are more important as technology develops. A headless content management system (CMS) might offer the answer you want, whether you're working with products, stock, people, books, or other objects. The benefits of adopting a headless CMS-based website will be discussed in this blog article, along with the relevance of constructing a content model that is in line with your goals and the two widely used patterns for building the data model. We'll also go through how to organize your website's information architecture to get the outcomes you want. Keep reading for more information on how a headless CMS might improve your data management approach.

Are you looking for an efficient way to store raw data about products, stock, people, books, or anything else? A headless content management system (CMS) might just be the solution you need. In this article, we'll look at how to structure a headless CMS-based website and design the content model to support your goals.

The first step in every headless CMS-based project is the information architecture, which refers to your data model. There are two common patterns for designing the model: a model built around raw data and a model that represents concepts like pages and their content.

Headless CMS can be used for storing raw data about products, stock, people, books or whatever else. But it can also hold information about the structure of pages on a website. Without sacrificing the benefits of a headless approach - we can also provide users with familiar and easy-to-use tools to control the appearance of their content and foster reuse of existing material. In this article, we will look at an approach to how to structure headless CMS-based websites and design the content model to support these goals.

Information architecture

What comes first in every headless CMS-based project is the information architecture. This means - your data model. There are 2 common patterns for designing the model:

  1. Model built around raw data, e.g. products and stock
  2. Model that also represents concepts like pages and their content.

While the first approach is absolutely correct, the second can easily become an anti-pattern of a headless CMS application. Let’s look a bit deeper into pros & cons of both.

Raw data pattern

In the raw data pattern, we take great efforts to eliminate (or at least greatly reduce) any signs of the presentation layer in our data model. Some models we might see in a project would be:

  • product
  • invoice

The purpose behind doing this is to make it easier to repurpose data for various channels. By removing the HTML or other forms that dictate how content should be displayed, it becomes simpler to reuse the same content on different devices. This is one of the primary advantages of using headless CMSs. However, there are some drawbacks to this approach. The headless CMS essentially acts as a minimal front-end to a database, which may not be ideal for content editors. All of the descriptions of how the content is displayed must be defined in code, which means any changes to the website's appearance require a developer's involvement. This lack of control is not what customers expect from platforms like Wix, WordPress, or Adobe Experience Manager, where they want some degree of control and the ability to make changes without needing to engage development teams constantly.

Visual model

Quite the opposite approach, one which tries to address the need to easily perform changes on the website, is to include a description of the visual representation of our content in the headless data model. What we might find in a project that follows this path is, for example:

  • page

Depending on the features provided by the headless CMS - content editors may have quite a bit of control over how the content is structured and rendered on a page. For example, Flotiq offers a block editor that allows authoring page sections using structured content blocks.

This approach, unfortunately, is very close to a headless CMS anti-pattern. Content stored in pages structured this way will likely be unusable in any channel except a website. Let’s look at an example page object, represented in JSON:

{
  "title": "About us",
  "url": "/about-us",
  "keywords": "company information",
  "header": "<h1>ACME company information page</h1>",
  "mainContent": "<h2>Company history</h2><img src=\"/media/team-photo.jpg\" alt=\"Our team in 2022 has grown to 20 people!\"/><p>Our company has been founded in 1999, just before Y2K.</p>",
  "footer": "<span style=\"font-size:8pt\">Call us at +1 (123) 456-789</span>"
}

Now - this will be easily rendered in a web browser, but what about a watch? Or what if you would like to send the company history information to a mobile phone in a text message? You will have to strip all the HTML, possibly removing some important information (like the contents of the alt attribute in the example above). Actually, you won’t even be able to reuse the information about company history on another page of your website - you would have to copy the entire page and only then start making adjustments. You will end up with a similar situation when using visual website builders.

Headless visual pattern

A sweet spot can be found between the 2 models above. A way to keep both - the editors wanting some flexibility and influence on the presentation layer and orthodox headless purists - happy. Let’s consider a specific example of a website selling tea. The basic data type, in this case, would be:

  • product
  • order

and providing this to content editors via a Headless CMS will allow them to easily add and update products as well as track orders. A very simple product detail page might look similar to the following (the code examples below are incomplete but are inspired by Next.js components):

export default function Product({ product }) {
  return (
    <div style="background-color: green">
      <h1>{product.name}</h1>
      <img src="{product.image}"/>
      <span><b>Price</b>{product.price}</span>
      <button>Buy</button>
    </div>
  )
}

That’s really straightforward. But will a content editor happily clone a Git repo, open up an IDE and change the background color of this page? Nope. So can we do anything about it?

Defining the architecture

In some cases, this might be an iterative process, but it usually starts with a simple question - what do you expect to update on the site, and how frequently will you do it? Based on the answers to these questions you will end up creating more or less complex content architecture. To address the situation in the example above - one might include in their content model (on top of the product and order content types) a productCard the model defined like this:

  • productCard

and the component would instantly become:

export default function Product({ product, productCard }) {
  return (
    <div style="background-color: {productCard.cardBackground}">
      <h1>{product.name}</h1>
      <img src="{product.image}"/>
      <span><b>Price</b>{product.price}</span>
      <button>Buy</button>
    </div>
  )
}

This mix of content types originating from the raw data model and ones more related to the visual representation is really powerful if you think about it. Let’s consider that on our website, we also have a number of informational pages which describe the process of growing tea, packaging it and brewing it. Our UI designer created a modern minimalistic design based on 2 kinds of sections:

Sections' mockup

Sections' mockup

Content in these sections is text and a related image, but we already know there will be situations when the editors might want to visually emphasise some of these descriptions. How could we organize this in a headless CMS? Let’s look at an example:

  • section
  • page

In the section content type we’ve identified several important patterns:

a) sections can have the image on either side but otherwise are the same,

b) background color should be changeable by the editors,

c) heading text should be split from the rest to simplify the presentation.

For the page content - we chose to compose the content of links to existing section objects (Flotiq supports relations/linking between objects of different content types). This way, sections can be used on different pages, and editors can even decide what goes on which page and in what order.

export default function Section({ props } ) {
  return (
    <div style="background-color:{props.backgroundColor}; display:flex">
      <div style="order: {props.variant == "leftTextRighImage" ? 1 : 2}">
        <h1>{props.heading}</h1>
        <span>{props.content}</span>
      </div>
      <div style="order: {props.variant == "leftTextRighImage" ? 2 : 1}">
        <img src="{props.image}"/>
      </div>
    </div>
  )
}
 export default function Page({ page }) {
  return (
    {page.sections.map((section) => (
        <Section section={section}/>
      ))}
  )
}

Data in Flotiq

The example above can be implemented in Flotiq very quickly. Here are our content type definitions first.

Section

Content type definition of a section

Content type definition of a section

Page

Content Type Definition of a page

Content Type Definition of a page

Objects

Example section

Example section

Once the CTDS are in place, we can start creating content. Here’s an example section:

and a page could be like this:

A page reusing existing section objects 

A page reusing existing section objects 

Summary

The primary advantage of headless CMS systems is that they separate data from its presentation, making it easier to repurpose the content for various channels. However, this division can cause problems with the authoring process and slow down development. On the other hand, prioritizing the presentation aspect can lead to a data model that does not allow for content reuse. By following the headless visual pattern, we can organize our content logically, map it onto code such as React components, and provide content editors with the ability to affect the presentation without requiring changes to the code.

By following this practical guide, you can successfully structure your content in a headless CMS to suit your needs without sacrificing the benefits of a headless approach.

Happy structuring!

Share on LinkedInShare on XShare on Facebook

Frequently Asked Questions

Flotiq team

Flotiq team

We’re a team of passionate developers dedicated to building innovative solutions and sharing our knowledge. From coding best practices to emerging tech trends, we explore it all. Our goal is to simplify complex concepts and empower developers of all levels. Join us as we learn, build, and grow together!

Posts related to Tutorials

Boost your SEO with Surfer plugin in Flotiq – quick demo
Tutorials

Boost your SEO with Surfer plugin in Flotiq – quick demo

Paweł Panowicz2 min read6 Feb 2025
How We Created a Top-Ranking SEO-Optimized Article in Record Time: A Step-by-Step Showcase
Tutorials

How We Created a Top-Ranking SEO-Optimized Article in Record Time: A Step-by-Step Showcase

Paweł Panowicz3 min read16 Jan 2025
From Gatsby to Next.js: Why We Migrated Our Blog and How You Can Too
Tutorials

From Gatsby to Next.js: Why We Migrated Our Blog and How You Can Too

Paweł Panowicz10 min read31 Dec 2024