Introduction
nextjs-cms is a CMS framework for Next.js. You describe your content in TypeScript section files, and it gives you an admin panel, MySQL tables, and a typed API.
Welcome to the nextjs-cms documentation. These pages are for developers building a CMS with nextjs-cms. If you want to work on nextjs-cms itself, head to the Contributing docs.
What is nextjs-cms?
nextjs-cms is a Next.js application plus a library. You install it as a project (the admin app), then describe your content in *.section.ts files:
sections/posts.section.ts
import { hasItemsSection } from 'nextjs-cms/core/sections'
import { richTextField, textField } from 'nextjs-cms/core/fields'
const title = textField({ name: 'title', required: true })
export default hasItemsSection({
name: 'posts',
order: 1,
title: { section: 'Blog', singular: 'Post', plural: 'Posts' },
headingField: title,
db: { table: 'posts' },
fields: [title, richTextField({ name: 'body' })],
})From that one file you get:
- An admin UI: sidebar entry, list page with search and pagination, create and edit forms, validation, and delete.
- A database table: running
nextjs-cms update-sectionscreatespostswithid,title,body,created_at,updated_at,created_by, andupdated_bycolumns. - Permissions: admins can be granted create, update, and delete rights on
posts, per admin. - An optional Drizzle schema for the table, so your public website can query the content with full types.
How it fits together
┌──────────────────────┐ update-sections ┌──────────────┐
│ sections/*.section │ ─────────────────────▶ │ MySQL │
│ cms.config.ts │ │ tables │
└──────────┬───────────┘ └──────▲───────┘
│ loaded at runtime │ reads/writes
▼ │
┌──────────────────────┐ tRPC ┌───────┴──────┐
│ Admin UI (Next.js) │ ◀──────────────────▶ │ nextjs-cms │
│ forms, lists, auth │ │ core + API │
└──────────────────────┘ └──────────────┘
▲
your public website ────┘ (reads the same tables)- You write section files and a
cms.config.ts. - The CLI (
nextjs-cms update-sections) reads your sections and syncs MySQL tables to match. - The admin app loads the same sections at runtime to render forms, validate submissions, and write rows.
- Your website reads the tables directly, optionally through the generated Drizzle schema.
Core concepts
| Concept | What it is |
|---|---|
| Section | A piece of content with its own table and admin pages. There are three types: simple (one row, e.g. settings), has-items (a collection, e.g. posts), and category (a tree, e.g. nested categories). |
| Field | One input in a section's form and one column in its table (with a few exceptions, like dateRangeField, which writes two columns). Created with helpers such as textField() or photoField(). |
| Field group | A titled group of fields, rendered as a card in the form. Purely visual. |
| Hooks | Functions that run before or after a create, update, or delete. Use them to validate, sync, or notify. |
| Plugin | An npm package that adds pages (and API routes) to the admin panel. |