@celar/git-cms
v1.0.6
Published
Git-based CMS for Next.js - Store content as markdown in GitHub
Downloads
788
Maintainers
Readme
@celar/git-cms
A Git-based CMS for Next.js. Content lives as markdown files in your GitHub repo — no database, no separate deployment.
What this package provides
- Admin UI at
/adminfor creating and editing content - GitHub OAuth authentication (via NextAuth v5)
- REST API for reading/writing markdown files to GitHub
- Schema system to define your content structure
- Utilities to read and render content in your frontend
You wire it into your Next.js app by creating a few files and defining your content schemas.
In your Next.js project
1. Install
npm install @celar/git-cms2. Files to create
your-app/
├── app/
│ └── admin/
│ ├── [[...cms]]/
│ │ └── page.tsx # renders the admin UI
│ └── api/
│ ├── auth/[...nextauth]/
│ │ └── route.ts # GitHub OAuth endpoint
│ └── cms/[...cms]/
│ └── route.ts # CMS read/write API
├── cms.config.ts # your content schemas
└── .env.local3. Admin page
app/admin/[[...cms]]/page.tsx
import { AdminPage } from '@celar/git-cms/core'
import { blockSchemas, pageSchemas } from '../../../cms.config'
export default function Page() {
return AdminPage({ blockSchemas, pageSchemas })
}4. Auth route
app/admin/api/auth/[...nextauth]/route.ts
export { handlers as GET, handlers as POST } from '@celar/git-cms/auth'5. CMS API route
app/admin/api/cms/[...cms]/route.ts
export { GET, POST, DELETE } from '@celar/git-cms/core'6. Define your schemas
cms.config.ts
import type { BlockSchema, PageSchema } from '@celar/git-cms'
export const blockSchemas: BlockSchema[] = [
{
type: 'hero',
label: 'Hero',
fields: [
{ name: 'heading', label: 'Heading', fieldType: 'text', required: true },
{ name: 'body', label: 'Body', fieldType: 'richtext' },
{ name: 'image', label: 'Image', fieldType: 'image' },
],
},
]
export const pageSchemas: PageSchema[] = [
{
type: 'page',
label: 'Page',
contentPath: 'content/pages', // folder in your GitHub repo
allowedBlocks: 'any',
},
]7. Environment variables
.env.local
GITHUB_OWNER=your-username
GITHUB_REPO=your-repo
AUTH_GITHUB_ID=your-oauth-app-id
AUTH_GITHUB_SECRET=your-oauth-app-secret
AUTH_SECRET=random-secret-string # openssl rand -base64 32Setup GitHub OAuth
- Go to GitHub → Settings → Developer settings → OAuth Apps → New OAuth App
- Fill in:
- Homepage URL:
http://localhost:3000 - Authorization callback URL:
http://localhost:3000/admin/api/auth/callback/github
- Homepage URL:
- Copy the Client ID →
AUTH_GITHUB_ID - Generate a Client Secret →
AUTH_GITHUB_SECRET - For production, create a second OAuth App with your live domain, or update the callback URL
Reading content in your frontend
Content is stored as markdown with YAML frontmatter in your GitHub repo. Read it server-side using the markdown utility:
import { parseMarkdown } from '@celar/git-cms/markdown'
import fs from 'fs'
const raw = fs.readFileSync('content/pages/home.md', 'utf-8')
const page = parseMarkdown(raw)
// page.title, page.slug, page.blocks[]Navigation
Pages opt in to navigation via frontmatter:
---
title: About
slug: /about
navEnabled: true
navTitle: About Us
navOrder: 2
navParent: /company # optional: nests under another page's slug
---Build a nav tree server-side:
import { buildNav } from '@celar/git-cms/nav'
const nav = buildNav(['content/pages'])
// nav.items[] sorted by navOrder, nested by navParentField types
| Type | Description |
|------|-------------|
| text | Single-line text |
| textarea | Multi-line text |
| richtext | Tiptap rich text editor |
| number | Numeric input |
| boolean | Toggle |
| image | Single image |
| imagelist | Multiple images |
| dropdown | Select — requires options: [{ label, value }] |
| pagepicker | Pick a page by slug — requires contentPath |
Package exports
| Import | Use |
|--------|-----|
| @celar/git-cms | Types, markdown utilities, settings utilities |
| @celar/git-cms/core | AdminPage, GET, POST, DELETE |
| @celar/git-cms/auth | handlers, auth, signIn, signOut |
| @celar/git-cms/markdown | parseMarkdown, serializeToMarkdown |
| @celar/git-cms/nav | buildNav |
| @celar/git-cms/styles | Scoped admin CSS |
License
MIT
