Introduction

Build a Headless Site with dotCMS

Welcome to this hands-on guide. You'll build a real banking company website powered by dotCMS and Next.js — from a blank project to a fully working site.

This is not a tour of features. You'll write real code, connect to a real CMS, and ship something that works.

What you'll build

A banking company site with three pages:

  • Home page — a hero banner and a curated list of blog posts, all managed in dotCMS

  • Blog listing page — a dynamic list of posts where a content author controls how many appear and which fields to show, without touching code

  • Blog detail pages — full article content, dynamically routed by slug

The site runs entirely on your machine — dotCMS locally via Docker, Next.js via the dev server.

What you'll learn

  • Routing — how to use Next.js catch-all routes to let dotCMS own the URL structure

  • dotCMS SDK — how to use @dotcms/client and @dotcms/react (part of the dotCMS SDK) to connect your app to dotCMS

  • Page API — how to fetch a page from dotCMS and render everything it contains

  • Component registry — how to map dotCMS content types to React components

  • Content API — how to fetch a collection of content server-side, and why it must stay server-side

  • Author-driven configuration — how content authors control frontend behavior through dotCMS content, without code changes

  • Block editor — how to render rich text content from dotCMS

  • Visual editing — how to enable in-context editing with the Universal Visual Editor

  • SEO — how to generate dynamic metadata, Open Graph tags, and canonical URLs from dotCMS content

  • Structured data — how to add JSON-LD so your pages are indexed correctly by search engines and surface in AI-generated answers

By the end, your site is production-ready — optimized for search, AI discovery, and real-time content editing from dotCMS.

How dotCMS structures content

Before writing any code, it helps to know how dotCMS thinks about pages and content. You'll see these terms throughout the course.

Page — in dotCMS, pages are content too. Authors create and manage them in the admin. This means dotCMS owns the URL structure — your Next.js app doesn't define routes for each page, it asks dotCMS what's at a given URL and renders whatever comes back.

Layout — the arrangement of containers on a page, defined by the page template. It also carries flags like header and footer that tell your frontend whether to render those elements.

Container — a slot on a page where authors place contentlets and widgets. A page can have multiple containers — a hero container, a main content container. The developer maps content types to components; the author fills containers with content.

Content Type — the schema. Defines what fields a piece of content has. Blog has title, body, author, image. Banner has title, caption, image, link. Authors create content from content types.

Contentlet — an instance of a Content Type. A specific blog post, a specific banner. Its fields become the props your React components receive.

Widget — a special content type whose purpose is to configure the frontend, not display content directly. The BlogList widget on the blog page has quantity and show fields — instructions for your code, not content to render.

URL Content Map — when a contentlet (like a blog post) is mapped directly to a URL. Instead of living in a container, it's accessible via pageAsset.urlContentMap when you fetch that URL.

Put together:

Page (owned by dotCMS, mapped to a URL)
└── Layout (header/footer flags, row/column structure)
    └── Containers (slots where authors place content)
        └── Contentlets / Widgets (instances of a Content Type → component props)

What's already set up

The starter project includes:

  • The dotCMS SDK installed (@dotcms/client and @dotcms/react)

  • Tailwind CSS configured

  • A dotCMS instance pre-loaded with content: a home page, a blog listing page, and three blog posts

You'll write all the pages and components. Everything else is ready.

Prerequisites

  • Node.js 18+nodejs.org

  • Docker Desktop installed and running — docker.com

  • Basic knowledge of React and Next.js — components, props, server components

Time to complete

30–60 minutes. Docker pulls images on the first run — that's the slowest part. Everything after that moves quickly.

Next up

Chapter 1: Set Up Your Project

Continue →