
Read me
Robin CMS
A modern, block-based content management system built with Payload CMS 3 and Next.js 15. Robin CMS gives content editors a visual, component-driven editing experience with a fully themeable frontend powered by Tailwind CSS 4, Motion (Framer Motion), and Material Design 3 design tokens.
Table of Contents
- Description
- Installation
- Usage
- Features
- Configuration
- Collections
- Blocks
- Vote Popup
- API Routes
- License
Description
Robin CMS is a headless CMS with a tightly integrated Next.js frontend. Pages are composed from a library of reusable content blocks, each with per-block color, spacing, and layout overrides. The admin panel provides color pickers that pull preset values straight from the global theme, making it easy to stay on-brand while still allowing creative flexibility per section.
Tech Stack
| Layer | Technology |
|---|---|
| CMS | Payload CMS 3 (v3.76.1) |
| Framework | Next.js 15 (App Router) |
| Runtime | React 19 |
| Database | MongoDB (via Mongoose adapter) |
| Styling | Tailwind CSS 4, CSS custom properties |
| Animation | Motion (Framer Motion) v12 |
| Rich Text | Lexical editor |
| Markdown | react-markdown, remark-gfm, rehype-highlight, rehype-slug |
| Media | Sharp image processing, Vercel Blob storage |
| Lightbox | yet-another-react-lightbox |
| Package Manager | pnpm |
Installation
Prerequisites
- Node.js
^20.9.0or>=22.0.0 - pnpm (recommended)
- MongoDB instance (local or Atlas)
Steps
bash# 1. Clone the repository
git clone https://github.com/<your-org>/robin-cms-payload.git
cd robin-cms-payload
# 2. Install dependencies
pnpm install
# 3. Create a .env file in the root
cp .env.example .env
# Then fill in the required values (see Configuration below)
# 4. Generate Payload types and import map
pnpm payload generate:types
pnpm payload generate:importmap
# 5. Start the dev server
pnpm dev
The site will be available at http://localhost:3000 and the admin panel at http://localhost:3000/admin.
Usage
Development
bashpnpm dev # Start Next.js + Payload in development mode
Production
bashpnpm build # Build for production
pnpm start # Start the production server
Other Commands
bashpnpm lint # Run ESLint
pnpm payload generate:types # Regenerate TypeScript types from Payload config
pnpm payload generate:importmap # Regenerate the admin import map
Features
- Block-Based Page Builder — Compose pages from 19 content blocks with drag-and-drop ordering in the admin panel.
- Global Theme & Styling — Centrally manage brand colors, surface colors, text colors, typography (Google Fonts), font scale, border radius, button styling, and animation settings.
- Per-Block Color Overrides — Every content block has a "Block Colors" group that lets editors override the background, primary text, and secondary text colors with a theme-aware color picker.
- Background Patterns — Layer any of 40 tileable SVG patterns (across 8 categories) over a block's background, with configurable pattern color and opacity.
- Per-Block Typography Overrides — Selected blocks expose a "Typography" group to override the font family, weight, and size for that block only, defaulting to the global theme.
- Per-Block Spacing Overrides — Blocks include a "Block Spacing" group for custom padding and margin (top/right/bottom/left) with preset and custom pixel values.
- Theme-Aware Color Picker — Admin color picker component that fetches live theme values and presents them as labeled quick-select presets alongside a full hex picker.
- Font Select Field — Admin font picker supporting Google Fonts with live preview for headings, body, buttons, and navigation.
- Responsive Design — Mobile-first layouts with Tailwind CSS 4 utility classes.
- Animations — Configurable entrance animations (fadeUp, fadeIn, slideLeft, slideRight, scale) per block, powered by Motion with spring physics. Animation intensity is globally adjustable (subtle/standard/expressive).
- Hero Scroll Effects — Optional scroll-driven visual effects on hero background images: Zoom In, Parallax Depth Shift, and Blur. Effects are powered by Motion's
useScroll/useTransformand can be switched off per block. - Rich Text Editing — Lexical-based rich text editor with inline toolbar, lists, links, media embeds, and more.
- Markdown Document Block — Write or upload GFM Markdown with syntax highlighting and auto-generated table of contents.
- Carousel Block — Image carousel with autoplay, snap scrolling, infinite loop, configurable aspect ratios, and lightbox-style captions.
- Card Grid Block — Versatile card layouts (standard, horizontal, overlay, minimal) with 1–4 column grids and per-card styling options.
- Contact Form Block — Built-in contact form with honeypot, timestamp, and rate-limit anti-spam protection. Submissions are stored in the Contact Messages collection.
- SEO Ready — Global SEO defaults, per-page meta overrides (title, description, keywords), Open Graph images, and robots.txt configuration.
- Header & Footer Builders — Configurable navigation with dropdown menus, CTA buttons, multi-column footers, social links, and newsletter section.
- Media Management — Automatic image resizing with Sharp (thumbnail, card, hero, og sizes), focal point editing, and optional Vercel Blob storage.
- Image Compressor — Built-in admin provider for client-side image compression before upload.
- Live Preview — Preview pages at mobile (375×667), tablet (768×1024), and desktop (1440×900) breakpoints directly in the admin panel.
- Saved Blocks Library — Save any configured block as a reusable template. Import saved blocks into any page with one click from the "Import Saved Block" drawer, organized by category with search.
- Version Control — Drafts with autosave and scheduled publishing for Pages.
- Vote / Feedback Popup — Scroll-triggered 5-star rating popup with optional text feedback. Configurable per-site via Site Settings. Both feedback fields (name and message) are fully optional — clicking Send with empty fields still shows the thank-you message.
- GraphQL & REST APIs — Auto-generated APIs for all collections and globals, plus custom vote endpoints.
Configuration
Environment Variables
Create a .env file in the project root with the following variables:
env# Required
MONGODB_URI=mongodb+srv://<user>:<password>@<cluster>.mongodb.net/<database>
PAYLOAD_SECRET=<a-long-random-string>
# Optional
NEXT_PUBLIC_SERVER_URL=http://localhost:3000
Global Settings (Admin Panel)
| Global | Path | Purpose |
|---|---|---|
| Site Settings | /admin/globals/site-settings | Site title, description, logos, favicon, SEO defaults, social links, analytics IDs, custom scripts, vote popup settings |
| Theme & Styling | /admin/globals/theme | Brand colors (primary, secondary, accent, highlight, dark), surface colors, text colors, typography & font scale, heading overrides (h1–h6), layout (container width, section padding, border radius), button styling & hover effects, animation settings |
| Header | /admin/globals/header | Logo, navigation items (up to 8) with dropdown children, CTA button, sticky/transparent options |
| Footer | /admin/globals/footer | Multi-column link lists (up to 4), description, newsletter section, bottom bar with copyright and links, optional social links |
Collections
| Collection | Slug | Description |
|---|---|---|
| Pages | pages | Content pages built from 19 blocks. Supports drafts, autosave, scheduled publishing, per-page SEO, and optional background color. |
| Media | media | Uploaded images, videos, and PDFs. Auto-generates thumbnail (400×300), card (768×512), hero (1920×auto), and og (1200×630) sizes. |
| Users | users | Admin and editor accounts with Payload built-in auth. Roles: admin, editor, or viewer (read-only). |
| Votes | votes | Stores star ratings and optional text feedback from the vote popup. Fingerprint-based duplicate prevention. Public read/create; authenticated update/delete. |
| Contact Messages | contact-messages | Stores contact form submissions (name, email, message). Public create; authenticated read/update/delete. Messages can be marked as read in the admin panel. |
| Saved Blocks | saved-blocks | Reusable block templates that can be imported into any page. Each entry stores a name, optional category, description, and a single configured block (15 block types supported). |
Blocks
Robin CMS includes 19 content blocks, each configurable with per-block color and spacing overrides:
| Block | Slug | Description |
|---|---|---|
| Hero | hero | Full-screen, split, centered, or minimal hero sections with background images, overlays, scroll-driven visual effects (zoom, parallax, blur), bottom gradients, and CTA buttons. |
| Rich Text | richText | Lexical rich text content with single or two-column layouts and configurable max widths (narrow/medium/wide/full). |
| Image + Text | imageText | Side-by-side image and rich text with configurable image size (33%/50%/66%), position, vertical alignment, and rounded corners. Supports an Image Only layout with 4 width options (small/medium/large/full), 12 image mask shapes (circle, rounded, blob, wave, heart, star, flower, burst, splash, torn paper, cross, teardrop), up to 3 CTA buttons (with optional Heroicons) below text, and a text-only layout option. |
| Call to Action | cta | Standard, banner, card, or inline CTA sections with up to 3 buttons (filled, outlined, tonal, text, elevated). |
| Accordion / Tabs | accordionTabs | Collapsible accordion or tabbed content with animated transitions, optional icons, and configurable default-open index. |
| Card Grid | cardGrid | Standard, horizontal, overlay, or minimal card layouts in 1–4 column grids with card styling variants (elevated/filled/outlined) and per-card buttons. |
| Carousel | carousel | Image carousel with standard, fill, or mixed layouts. Supports autoplay, snap scrolling, infinite loop, arrow/dot navigation, and configurable aspect ratios. |
| Quote / Testimonial | quote | Card, minimal, or large-featured quote styles with author info, role, and avatar. |
| Photo Gallery | gallery | Grid, masonry, carousel, or single-featured layouts with lightbox support, configurable columns, and rounded corners. |
| Bento Gallery | bentoGallery | Scroll-driven bento-grid gallery with a Ken Burns zoom that animates toward a focus image, plus an optional floating title with configurable visibility. |
| Video | video | YouTube and Vimeo embeds with custom poster images, aspect ratios (16:9, 4:3, 1:1), and configurable max widths. |
| Markdown Document | markdownDoc | GFM Markdown content written in-editor or uploaded as a .md file. Auto-generates table of contents from headings. Supports syntax highlighting. |
| Embed | embed | Raw HTML embed code for iframes, widgets, maps, etc. Configurable max width and alignment. |
| Separator | separator | Decorative dividers — wave, blob, hand-drawn, slant, or simple line — with color, gradient, flip, and animation options. |
| Spacer | spacer | Vertical spacing with preset sizes (32–128 px) or custom pixel heights (8–500 px). |
| Contact Form | contactForm | Contact form with name, email, and message fields. Anti-spam protection via honeypot, timestamp check, and IP rate limiting. Submissions saved to the Contact Messages collection. |
| Timeline | timeline | Horizontal (immersive, full-background-image tabs) or vertical (classic alternating left/right) timeline layout. Items have a date label, title, subtitle, description, and optional image. |
| Horizontal Text | horizontalText | Marquee-style text that scrolls horizontally across the screen, with configurable font, weight, size, speed, direction, separator, and an optional letter fly-in animation. |
| Vinyl Player | vinylPlayer | Interactive turntable showcase that slides up to 5 records onto a spinning vinyl, each with a cover sleeve, center label, track details, and optional audio playback. |
Saved Blocks (Reusable Block Templates)
The Saved Blocks collection lets editors save fully configured blocks as reusable templates. When editing a page, click the "Import Saved Block" button above the layout blocks area to open a slide-out drawer where you can browse, search, and filter saved blocks by category, then import them into the page with one click.
How It Works
- Create a saved block — Go to
/admin/collections/saved-blocksand click "Create New". Give it a name, pick a category, and configure the block exactly as you want it. - Import into a page — Open any existing page, click "Import Saved Block" in the Content tab, and select a template from the drawer. The block is appended to the page layout with all its saved settings.
- Customise per page — After importing, you can edit any field on the imported block without affecting the original saved template.
Categories
| Category | Intended Use |
|---|---|
| Heroes | Hero section templates |
| Content | Rich text, accordion, embed blocks |
| Media | Gallery, carousel, video blocks |
| Navigation | Navigation-related blocks |
| Call to Action | CTA block templates |
| Testimonials | Quote / testimonial blocks |
| Layout | Spacer, separator, structural blocks |
| Other | Everything else |
Note: The page must be saved at least once before importing saved blocks (the import uses the REST API to append the block to the page layout).
Per-Block Color Overrides
Every content block (except Spacer and Separator) includes a Block Colors group with:
- Background Color — Override the section background.
- Primary Text Color — Override heading and body text color (
--color-text-primary). - Secondary Text Color — Override subtitle and caption color (
--color-text-secondary). - Button Background / Text Color — Override the filled-button colors for the block.
- Background Pattern — Layer one of 40 tileable SVG patterns over the background, with configurable pattern color and opacity.
Each color field uses the theme-aware color picker that shows your theme's saved colors as labeled presets for quick selection.
Per-Block Spacing Overrides
All blocks include a Block Spacing group with two collapsible sub-groups:
- Padding — Top, Right, Bottom, Left (none/small/medium/large/custom with pixel value).
- Margin — Top, Right, Bottom, Left (same options).
Hero Scroll Effects
The Hero block supports an optional Scroll Effect that animates the background image as the section scrolls out of the viewport. The field only appears when a background image is set and defaults to None (off).
| Effect | Value | Behaviour |
|---|---|---|
| None | none | No scroll-driven effect (default). |
| Zoom In | zoomIn | The background image scales from 1× to 1.25× as the hero scrolls out of view. |
| Parallax Depth Shift | parallax | The image translates vertically at 30 % of the scroll speed, creating a depth/layering illusion. |
| Blur | blur | The image progressively blurs from 0 px to 20 px as it exits the viewport. |
Effects are implemented with Motion's useScroll and useTransform hooks and applied to a motion.div wrapper around the hero image. The hero section uses overflow-hidden to prevent visual overflow from zoomed or shifted images.
Vote Popup
A scroll-triggered feedback widget that collects star ratings and optional text feedback from visitors.
How It Works
- Scroll trigger — The popup appears once the user has scrolled past a configurable percentage of the page (default: 75 %).
- Star rating — A 5-star system with emoji feedback (😡 → 🤩). Clicking a star immediately submits the rating via
POST /api/vote. - Optional feedback — After rating, a reply form slides in with a "First name" input and a free-text textarea. Both fields are fully optional — clicking "Send Feedback" with empty fields immediately shows the thank-you message without making an additional API call.
- localStorage persistence — Votes and dismiss state are persisted so the popup won't re-appear after a vote or explicit dismiss.
- Minimize / Dismiss — Users can minimise the popup to a floating pill or dismiss it entirely.
- Average score — After submission the popup fetches and displays the average score for the current block.
- Delete vote — A "Delete my vote" link allows users to remove their rating.
Configuration (Admin → Site Settings → Vote Popup)
| Setting | Default | Description |
|---|---|---|
| Enabled | false | Toggle the popup on/off site-wide |
| Scroll % | 75 | Page scroll percentage to trigger visibility (5–100) |
| Block ID | site-popup-vote | Identifier for grouping votes |
| Heading | How was your experience? | Popup title |
| Subheading | Your feedback helps us improve. | Popup subtitle |
| Reply Prompt | Tell us more about your experience... | Textarea placeholder |
| Thank You Message | Thank you for your feedback! | Shown after submission |
| Accent Color | #ff9529 | Star and highlight color (theme-aware picker) |
| Background Color | — | Popup card background (theme-aware picker) |
| Text Color | — | Primary text color (theme-aware picker) |
| Text Secondary Color | — | Secondary text color (theme-aware picker) |
| Border Radius | global | global / 0 / 4 / 8 / 16 / 24 / 9999 |
| Shadow | large | none / small / medium / large |
API Routes
Viewer (Demo) Role
Robin CMS includes a Viewer role designed for demo or stakeholder access. A viewer can log into the admin panel and browse every collection and global, but cannot create, update, or delete any content.
| Role | Read | Create | Update | Delete |
|---|---|---|---|---|
| Admin | Yes | Yes | Yes | Yes |
| Editor | Yes | Yes | Yes | Yes |
| Viewer | Yes | No | No | No |
To create a demo account, go to Users → Create New in the admin panel and set the role to Viewer.
| Method | Endpoint | Description |
|---|---|---|
POST | /api/contact | Submit a contact form message. Includes honeypot, timestamp, and rate-limit anti-spam checks. |
POST | /api/vote | Submit a star rating (1–5) for a block. Fingerprint-based duplicate detection. Can also update an existing vote with a reply and first name. |
DELETE | /api/vote | Delete a single vote by voteId, or all votes for a block by blockId. |
GET | /api/vote-results | Returns aggregated results: total votes, per-block average ratings, score distributions (1–5), and text replies. |
* | /api/[...slug] | Auto-generated Payload REST API for all collections and globals. |
* | /api/graphql | Auto-generated Payload GraphQL endpoint. |
License
MIT