A Git-based Content Management System (CMS) designed specifically for the Astro ecosystem. It allows you to manage your Content Collections through an intuitive visual interface, syncing data directly with your GitHub repositories.
- π GitHub OAuth Authentication - Secure connection with your GitHub account
- βοΈ GitHub App Onboarding - Guided flow to install and configure permissions
- π¦ Automatic Import - Scans and imports Markdown files from your repositories
- βοΈ Visual Editor - Modern interface for editing metadata and content
- ποΈ Dynamic Fields - Support for transcriptions and complex fields
- π Bidirectional Sync - MongoDB as cache + Git as source of truth
- β Zod Validation - Type-safety throughout the process
- π Automatic Commits - Saves changes directly to GitHub
- Framework: Next.js 16 (App Router)
- Authentication: NextAuth.js v5 with GitHub OAuth
- Database: MongoDB (Atlas)
- Git API: Octokit
- Markdown Parsing: gray-matter
- Validation: Zod
- Styles: Tailwind CSS v4
- Node.js 20+ and npm
- MongoDB Atlas account (free)
- GitHub account
- GitHub App configured (see instructions below)
git clone <your-repo>
cd cms
npm install- Create an account at MongoDB Atlas
- Create a new cluster (M0 - free)
- Create a database user
- Get your connection string
Quick Guide:
- Go to GitHub Apps
- Configure:
- GitHub App name: Broslunas CMS (or your preference)
- Homepage URL:
http://localhost:3000 - Callback URL:
http://localhost:3000/api/auth/callback/github - Webhook: Disabled
- Repository Permissions:
- Contents:
Read and writeβ VERY IMPORTANT - Metadata:
Read-only(automatic)
- Contents:
- Save the Client ID and generate a Client Secret
- Copy the App Slug (appears in the URL after creation)
- Install the app on your GitHub account
π Complete Documentation: See GITHUB_APP_SETUP.md for detailed step-by-step instructions.
Create a .env file in the project root:
# MongoDB
MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/astro-cms?retryWrites=true&w=majority
# NextAuth
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=generate-a-random-secret-here
# GitHub App (NOT OAuth App)
GITHUB_ID=your-github-app-client-id
GITHUB_SECRET=your-github-app-client-secret
GITHUB_APP_NAME=your-github-app-slugGenerate NEXTAUTH_SECRET:
openssl rand -base64 32npm run devOpen http://localhost:3000 in your browser.
- Click on "Continue with GitHub"
- Authorize the application
- You will be redirected to the dashboard
- In the dashboard, select a repository
- Click on "Import"
- The system will scan
src/content/looking for.mdand.mdxfiles - Posts will be imported into MongoDB
- Click on a post from the list
- Edit metadata (title, slug, tags, etc.)
- Edit transcriptions if available
- Edit markdown content
- Save: Saves only to MongoDB (status: "modified")
- Save & Commit: Saves to MongoDB and commits to GitHub (status: "synced")
βββββββββββββββ
β Next.js β
β (Frontend) β
ββββββββ¬βββββββ
β
ββββββββββββββ
β β
v v
βββββββββββ ββββββββββββ
β MongoDB β β GitHub β
β (Cache) β β (Source) β
βββββββββββ ββββββββββββ
Data Flow:
- Import: GitHub β MongoDB
- Edit: UI β MongoDB
- Commit: MongoDB β GitHub (with Markdown serialization)
app/
βββ api/
β βββ auth/[...nextauth]/ # Auth endpoints
β βββ repos/ # List repositories
β βββ import/ # Import content
β βββ posts/ # Post CRUD
βββ dashboard/
β βββ page.tsx # Main Dashboard
β βββ repos/ # Post list
β βββ editor/[id]/ # Post editor
components/
βββ LoginButton.tsx
βββ RepoSelector.tsx
βββ PostEditor.tsx
lib/
βββ auth.ts # NextAuth config
βββ mongodb.ts # MongoDB client
βββ octokit.ts # GitHub API utilities
βββ markdown.ts # Parsing/serialization
βββ schemas.ts # Zod validation
{
_id: ObjectId,
userId: string, // NextAuth user ID
repoId: string, // "owner/repo"
filePath: string, // "src/content/blog/post.md"
sha: string, // SHA of the file on GitHub
metadata: {
title: string,
slug: string,
tags: string[],
episodeUrl?: string,
transcription?: [{
time: string,
text: string
}]
},
content: string, // Markdown body
status: "synced" | "draft" | "modified",
lastCommitAt: Date,
createdAt: Date,
updatedAt: Date
}- Verify that GitHub scopes include
repo - Log out and authenticate again
- The file was modified externally
- Sync changes from GitHub or overwrite manually
- Verify the repository has a
src/content/folder - Verify files have valid frontmatter
- Phase 1: MVP (Auth, import, basic editor)
- Phase 2: Advanced dynamic forms
- Phase 3: Webhooks for real-time sync
- Phase 4: Media library (image management)
- Phase 5: Live preview
MIT
Contributions are welcome! Please open an issue or PR.
Made with β€οΈ for the Astro ecosystem