A super-powered, WordPress-like CMS with a decoupled Jamstack frontend.
This platform provides a powerful, flexible, and developer-friendly CMS experience with a modern, fast, and scalable frontend. It combines the best of a traditional CMS with the performance and security of the Jamstack.
⚠️ Note: The one-click deploy button requires the Railway template to be published first. See RAILWAY_TEMPLATE_SETUP.md for instructions on creating and publishing the template. For manual deployment, see DEPLOY_TO_RAILWAY.md.
- The Vision
- Why This Isn’t Just Payload
- Quick Start
- Core Features
- Dynamic Content Types
- Admin UI Features
- Project Structure
- Built-in Content Types
- Content Blocks
- Frontend Selection
- Makefile Commands
- Deployment
This platform is designed to be a super powerful but simple CMS, inspired by the best parts of WordPress but with a modern, headless architecture.
-
Shared Foundation: Every site starts with essential features like Pages, Categories, Tags, Media, and Globals.
-
Dynamic Content Types: Create custom content types like "Classic Cars", "Recipes", or "Products" directly from the admin UI - no server restart required.
-
Block-Based Editing: All content types support flexible block-based layouts with 9+ pre-built blocks.
-
Intuitive UX: The admin panel is designed for content editors, not just developers.
This repo is a productised platform on top of Payload CMS, not a vanilla clone:
- Dynamic Content Types: WordPress-style custom post types you can create from the dashboard (Content Type Manager) with no code or restarts; items live in
custom-itemswith shared blocks and media. - Dual Frontends Included: Next.js (ISR-ready, on-demand revalidation) and Astro (pure SSG) ship together, wired to the same CMS contracts and template system.
- Template + Block System: Finite, shared templates and 9+ reusable blocks across CMS/Next/Astro for consistent rendering without per-collection view code.
- Presets & Starters: Prebuilt starters (blog, brochure, archive, ecommerce) plus Makefile and
scripts/create.shworkflows to scaffold quickly. - Enhanced Admin UX: Two-panel nav, custom dashboard, theme toggle, and the Visual Template Gallery for layout selection.
- Operational Extras: Railway-ready multi-service deploy, Makefile one-command workflows, seed/reset endpoints, search/SEO/redirects/nested docs/form-builder plugins enabled, optional S3 storage.
- Rich Seed Data: Automated generation of complete sites including Pages, Posts, Products, Orders, and skin-specific Showcases (
/agency,/minimal,/retro).
Note: Template must be published first. See RAILWAY_TEMPLATE_SETUP.md for setup instructions.
# Clone the repository
git clone https://github.com/OpaceDigitalAgency/headless-cms.git
cd headless-cms
# Start everything with one command
make quickstartThis will:
- ✅ Create
.envfiles from examples - ✅ Install all dependencies
- ✅ Start PostgreSQL via Docker
- ✅ Run database migrations
- ✅ Seed sample data
- ✅ Start CMS on http://localhost:3000
Then create your first admin user:
- Open http://localhost:3000/admin/create-first-user
- Fill in your credentials
- Start using the CMS!
See QUICK_START.md for detailed setup instructions.
The Astro app now fetches content from the CMS REST API (no direct DB access). This keeps builds portable and avoids DB driver issues in build environments.
Required env vars for Astro builds:
PUBLIC_CMS_URL(e.g.http://localhost:3000)PUBLIC_SITE_URL(e.g.http://localhost:4321)
If you want sitemap generation, set ENABLE_SITEMAP=true before building.
| Feature | Description |
|---|---|
| Dynamic Content Types | Create custom content types from the admin UI without server restarts |
| Block-Based Page Builder | 20+ pre-built blocks for flexible layouts |
| Dual Frontend Support | Next.js 15 and Astro 4 frontends included |
| Version History | Full version control with restore capability on all collections |
| Live Preview | Real-time editing preview |
| On-Demand Revalidation | Fast, static pages with instant updates |
| One-Click Deploy | Deploy to Railway instantly |
| S3 Storage | Local or S3-compatible file storage |
| Visual Template Gallery | Visual layout picker for Pages, Posts, and Products |
| Advanced Seed Data | Rich, preset-specific content generation with media |
The key feature that makes this CMS WordPress-like is the Dynamic Content Types system.
- Go to Dashboard → Click the 🗂️ Content Types tab
- Create a new type (e.g., "Classic Cars", "Recipes", "Products")
- Choose a base template (Archive Item, Product, Person, Place, Event, Article)
- Add custom fields specific to your content type
- Start creating content - no server restart needed!
- Navigate to Dashboard → 🗂️ Content Types
- Click + New
- Enter "Classic Cars" as the name
- Select "Archive Item" as the template
- Click Create
- Your new content type is ready to use immediately!
All items are stored in the custom-items collection with a contentType field, similar to how WordPress stores all post types in wp_posts.
The admin UI has been completely redesigned for a modern, intuitive experience:
- Collapsible sidebar with icons
- Top bar with quick access to all sections
- Smooth transitions between states
- Search content, settings, and navigation items
- Keyboard shortcuts (Enter to navigate, Escape to close)
- Light and dark mode support
- Persists across sessions
- Collection stats at a glance
- Recent updates list
- Drafts needing review
- Quick create buttons
- Site configuration shortcuts
- Publishing calendar
- SEO audit tools
- Media management
- User administration
headless-cms/
├── apps/
│ ├── cms/ # Payload CMS application
│ │ ├── src/
│ │ │ ├── admin/ # Custom admin components
│ │ │ ├── blocks/ # Content block definitions
│ │ │ ├── collections/ # Collection configurations
│ │ │ ├── components/ # React components
│ │ │ ├── endpoints/ # Custom API endpoints
│ │ │ ├── globals/ # Global configurations
│ │ │ └── seed/ # Database seeding
│ ├── web/ # Next.js frontend
│ └── astro/ # Astro frontend
├── packages/
│ └── shared/ # Shared types & utilities
├── presets/ # Project presets
├── docs/ # Documentation
├── AGENT_CONTRACT.md # Developer contract
└── Makefile # All commands
These are the content types available out of the box (plus Dynamic Content Types you create in the admin):
- Pages (
pages) - Posts (
posts) - Categories (
categories) - Media (
media) - Archive Items (
archive-items) - People (
people) - Places (
places) - Content Types (
content-types) - dynamic content type definitions - Custom Items (
custom-items) - instances of dynamic content types - Users (
users) - Orders (
orders) - Carts (
carts) - Product Reviews (
product-reviews) - Services (
services) - Courses (
courses) - Testimonials (
testimonials) - FAQs (
faqs) - Galleries (
galleries)
- Header (
header) - Footer (
footer) - Settings (
settings)
All content types support these pre-built blocks:
| Block | Description |
|---|---|
| Hero | Full-width hero section with heading, subheading, background, and CTAs |
| Content | Rich text with optional column layouts |
| Media | Images and videos with captions |
| CTA | Call-to-action sections with buttons |
| Quote | Pull-quote with attribution and alignment options |
| Features | Feature list with icons or media |
| Stats | Key metrics and KPI highlights |
| Logo Cloud | Brand/logo grid with optional links |
| Testimonials | Quote cards with avatar and rating |
| FAQ | Collapsible Q&A list |
| Pricing | Pricing tiers with feature lists |
| Team | Team members with bios and social links |
| Embed | Responsive iframe embeds (video, maps, etc.) |
| Grid | Flexible grid layouts for cards and features |
| Timeline | Chronological timeline displays |
| Archive | Collection listings from any content type |
| Form | Form builder integration |
| Gallery | Image galleries (grid, masonry, carousel, lightbox) |
| Spacer / Divider | Vertical spacing and separators |
| Custom HTML | Render trusted HTML markup |
The Template Gallery provides a visual way to select layouts for Pages, Posts, and Products.
- Visual Preview: Browse templates with representative icons and descriptions.
- Auto-Population: Selecting a template (e.g., "Landing Page", "Case Study", "Product Bundle") automatically populates the content blocks.
- Smart Remediation: Works seamlessly with existing content, warning before overwrites.
This platform includes a robust Skin System that allows for radical design changes via CSS tokens, without altering the underlying React components or block structure.
We include dedicated showcase pages to demonstrate what's possible:
- /agency: High-contrast, bold typography, "Agency" aesthetic.
- /minimal: Clean, whitespace-heavy, centered "Minimal" aesthetic.
- /retro: A nostalgic "Retro Dreams" 80s/90s aesthetic.
These pages are automatically restored when running seed commands, ensuring you always have working demos.
You can choose your frontend framework in the admin panel:
- Go to Settings → Frontend
- Select your Framework (Next.js or Astro)
- Select your Site Type (Brochure, Blog, Museum, Ecommerce, Portfolio, Custom)
- Configure Frontend URL for preview links
- Toggle Features (Blog, Search, Forms, Comments, Newsletter, Multi-language)
| Command | Description |
|---|---|
make quickstart |
First-time setup: installs, configures, and starts everything |
make dev |
Start all development servers |
make build |
Build all applications for production |
make up |
Start services via Docker Compose |
make down |
Stop all running services |
make db-fresh |
Quick dev database refresh (uses push mode, no migrations) |
make db-fresh-migrations |
Fresh database with regenerated migrations (for production deployment) |
make db-migrate |
Run database migrations |
make db-reset |
Reset database (drop all tables and re-migrate) |
make db-seed |
Seed database with sample data |
make seed |
Seed database with sample data (default preset) |
make seed-with-media |
Seed database AND download sample media |
make seed-blog |
Seed specific data for Blog preset |
make seed-archive |
Seed specific data for Archive preset |
make seed-ecommerce |
Seed specific data for Ecommerce preset |
make clear-seed |
Clear all sample data |
make lint |
Run ESLint |
make typecheck |
Run TypeScript type checking |
make format |
Format code with Prettier |
For daily development work (fastest option):
make db-freshThis will:
- Stop any running dev servers
- Remove the database volume and recreate PostgreSQL
- Schema auto-syncs on first connection (push mode)
Then start the dev server:
make devCreate your admin user at http://localhost:3000/admin/create-first-user and run seed scripts from within the CMS.
When making core schema changes that need to be deployed to production:
make db-fresh-migrationsThis will:
- Stop any running dev servers
- Remove the database volume and recreate PostgreSQL
- Clear all old migration files
- Generate fresh migrations from your current Payload schema
- Run the new migrations
Then commit and push the new migration files to deploy to Railway.
| Command | Description |
|---|---|
make blog-astro |
Create a new blog project with Astro |
make brochure-astro |
Create a new brochure site with Astro |
make archive-next |
Create a new archive site with Next.js |
make ecommerce-next |
Create a new ecommerce site with Next.js |
This project is optimized for deployment on Railway.
Once the Railway template is published, users can deploy with a single click:
- Click the "Deploy on Railway" button
- Wait for automatic provisioning (PostgreSQL, CMS, Web services)
- All environment variables are auto-configured
- Access your CMS at the provided URL
What Gets Deployed Automatically:
- ✅ PostgreSQL database
- ✅ CMS service (Payload CMS)
- ✅ Web service (Next.js frontend)
- ✅ All environment variables configured
- ✅ Services linked together
- ✅ Public domains generated
For detailed manual deployment instructions, see DEPLOY_TO_RAILWAY.md.
To create your own Railway template for one-click deployment:
- Deploy the project manually first (see DEPLOY_TO_RAILWAY.md)
- Verify everything works correctly
- Follow the template creation guide in RAILWAY_TEMPLATE_SETUP.md
- Publish the template through Railway dashboard
- Update the deploy button URL in this README
The following environment variables are automatically configured when using the template:
CMS Service:
DATABASE_URL- Auto-linked from PostgreSQLPAYLOAD_SECRET- Auto-generatedPAYLOAD_PUBLIC_SERVER_URL- Auto-set from domainNODE_ENV- Set toproduction
Web Service:
DATABASE_URL- Auto-linked from PostgreSQLCMS_URL- Auto-linked from CMS serviceNEXT_PUBLIC_CMS_URL- Auto-linked from CMS serviceNEXT_PUBLIC_SITE_URL- Auto-set from domainREVALIDATION_SECRET- Auto-generatedNODE_ENV- Set toproduction
- Agent Contract - Developer guidelines
- Revalidation Rules - Cache invalidation
- Versioning Policy - Version management
This project is licensed under the MIT License. See the LICENSE file for details.
This project is developed and maintained by Opace Digital Agency, a Birmingham-based digital agency specializing in open-source solutions and custom developments.
We provide expert decoupled Next.js and Astro development services, creating modern, high-performance web applications and headless CMS solutions.
- Next.js & React Development - Custom web applications and JAMstack solutions
- Headless CMS Solutions - Payload CMS, Strapi, and custom implementations
- Frontend Development - Modern frameworks including Astro, React, and Vue
- WordPress Development - Custom themes, plugins, and headless WordPress
- E-commerce Solutions - Magento, WooCommerce, and custom platforms
- Website: https://opace.agency
- Services: Web Design & Development
- Location: Birmingham, UK
- GitHub: @OpaceDigitalAgency
For project inquiries, technical support, or collaboration opportunities, visit our website or reach out through our contact page.