Essential content models for building modern websites

Ronak Ganatra
Ronak Ganatra

February 20, 2021

Essential content models for building modern websites

When setting out to build modern websites with a Headless CMS - a solid foundation of Content Modeling is key. Websites today, particularly those for SaaS products and eCommerce, are transactional in nature. This means that while they house content critical to the business, they also require the ability to enable payments and transactions, usually in tandem with external services like Stripe or Adyen

This is why, ensuring a sound content modeling strategy is critical to ensure a well-maintained build of pages and posts, stretching to pages that communicate with external services, like /pricing, and /jobs.

To visualize some of the most important content models that contribute to such websites, let’s illustrate the blocks that make up the schema of one of our examples - Marketing Websites with Headless CMS. This website demo is built using GraphCMS, Next.js. and Tailwind UI, and is deployed on Vercel.

Marketing Websites with Headless CMS

Core Website Models

Let’s explore the primary content models that enable this website to be a functional site for SaaS products.

Blog Post

Blog Post

The blog model is a simple one that focuses on the content above all else, that uses a Rich Text Field to render the content. The posts further comprise author information, headers, cover images, and SEO.



The FAQ Markup is treated as a standalone content type by Google, critical to stronger SEO for queries that ask questions your website can answer. This GraphCMS project also uses FAQ as its own content model, related to different pages and grids, and can be queried when required.


The content for the footer is also handled via the CMS for this instance - particularly useful for when the content needs to be changed and/or localized by editorial teams. The footer follows a 2-column layout, with Primary and Secondary links.



Arguably one of the most important models in this project, the Grid is responsible for rendering as USPs, Features, or other listable items across the projects. Using enumerations, the grid can be rendered in multiple formats such as SPLIT and STACK, as well as with a LIGHT and DARK theme.



The hero for each page is defined within the CMS, with the option of setting custom buttons, images, and headers. Examples of this can be found on and, both of which are heroes following the same theme with different content.


Similar to the footer, the main navigation of the website is handled via GraphCMS. While not a necessity for simple static navigation, websites with more complex needs, frequent changes, and localized navigations can benefit from managing this in the CMS. Simple navigation is just a relation to several pages, as is in this case, however, a more complex structure can include nested pages, language switchers, and more.


Landing Page

The Page model is a relatively simple one exploiting the benefits of GraphQL Union Types - available out of the box in GraphCMS. Union Types allow for better organization of relations, such as grids, banners, and blocks in this case. A powerful feature for editors to better visualize the final page, this example has simplified the relations further by splitting them between Blocks, Navigation, Hero, and Marketing, for teams to know exactly what blocks they’re applying to which category.

Pricing Plan

Pricing Plan

Pricing plans are a simple setup, with one content item per Plan, in this case, FREE, STARTER, TEAM, and ENTERPRISE, as seen on the pricing page. Each plan simply requires a name, description, included features, and prices, and is rendered as a 4-column table.

GraphCMS’s tiers allow for Remote Fields - a powerful feature of extending GraphCMS’s API to communicate with other services like Stripe. A great example of how this works can be seen on this pricing page repository, where Jonathan uses remote fields with Next.js and Stripe, resulting in this.


Headless CMS SEO

We’ve written at length about SEO and Headless CMS, How we handle SEO at GraphCMS, and handling SEO for Assets with GraphCMS. Most of those examples highlight the setup of us using SEO.js when building our pages with Gatsby. However, given that the marketing project is built using Next.js, the component for SEO is slightly different in comparison. Here’s seo.js from the marketing website repository.

import { NextSeo } from 'next-seo'
import { useRouter } from 'next/router'
import { defaultUrl } from '../next-seo.config'
function SEO({ id, image, keywords, noIndex: noindex = false, ...props }) {
const router = useRouter()
const SEO = {
...(keywords && { keywords: keywords.toString() }),
openGraph: {
...(image && {
images: [
alt: props.title,
url: defaultUrl + router.asPath,
return <NextSeo {...SEO} />
export default SEO

Marketing Components

As with all things marketing, it’s time for Form to meet Function. Here are some of the marketing components implemented on the site.

Marketing Banner

A simple strip banner that can be applied on the top of specific pages, showcasing promotional text and a CTA.

Newsletter Signup

This website has a simple setup for capturing emails for newsletter signups. To learn more about programmatically creating forms and capturing submissions with Next.js and GraphQL, refer to Jamie’s blog post coving the topic at length.

Pop Up

Pop up

Commonly used for time-critical information and promotions, implementing pop-ups can be done within GraphCMS itself. Here we have a very simple example using a promotional image, with a title and description, before setting a CTA. The Pop-Up model can be related to pages as required, and the codebase can define additional criteria for setting conditions and triggers, usually in tandem with a CDP.



Testimonials and Social Proof are a great way to show trust in your website for your product. The website example uses localized testimonials with a simple text editor for adding the content in English and German. Each testimonial has a relation to the person attributed to the quote, as well as to the pages they should show on.

All Coming Together

All these components come together to power the website, with all the content for posts and pages handled from within GraphCMS itself.


While the content setup of the index, or homepage itself is highly straightforward, this is how simple it is to put everything together using Next.js.

import { getPageLayout } from '@/layout'
import { graphcmsClient } from '@/lib/_client'
import { pageQuery } from '@/lib/_queries'
import { parsePageData } from '@/utils/_parsePageData'
import Wrapper from '@/components/wrapper'
function IndexPage({ page }) {
return <Wrapper {} />
export async function getStaticProps({ locale }) {
const { page } = await graphcmsClient.request(pageQuery, {
slug: 'home'
return {
props: {
page: await parsePageData(page)
revalidate: 3
IndexPage.getLayout = getPageLayout
export default IndexPage

We recently tweeted the visualized schema of the GraphCMS website. By simply adding /voyager as a suffix to your GraphCMS GraphQL endpoint, you can visualize your own project’s schema. The schema for this particular website project looks something like this.

Marketing Website Schema

This site uses cookies to provide you with a better user experience. For more information, refer to our Privacy Policy