Visual Page Builder
Design landing pages with drag-and-drop components and AI-assisted content generation. The visual editor is powered by Puck Editor and saves content as real Drupal paragraph entities.
Overview
The visual page builder gives marketers and content editors a no-code way to create and edit landing pages. Developers set up the components once — then editors can mix, match, and customize them without writing code.
Key features:
- Drag-and-drop 10 component types onto a visual canvas
- AI chat assistant generates pages from natural language prompts
- Live preview as you edit
- One-click publish to Drupal
- Content saves as structured paragraph entities (searchable, translatable, revisioned)
- Cloudinary integration for image uploads
Quick Start with Decoupled Components
The Decoupled Components starter includes the visual editor pre-configured.
# 1. Clone the starter
npx degit nextagencyio/decoupled-components my-site
cd my-site
npm install
# 2. Run setup (creates Drupal space + imports content)
npm run setup
# 3. Build and run (production mode required for Puck)
npm run build
npm start
The setup script automatically:
- Creates a Drupal space with all paragraph types
- Enables the
dc_puckmodule - Configures the visual editor for
landing_pagecontent type - Imports sample content with 10 component demos
How It Works
Architecture
Drupal (CMS) Next.js (Frontend + Editor)
├── dc_puck module ├── /editor/[nid] ← Visual editor
│ ├── Design Studio tab ├── /node/[nid] ← Preview
│ ├── PuckMappingService ├── /api/drupal-puck/ ← Drupal proxy
│ ├── /api/puck/load/{nid} ├── /api/ai/generate ← AI generation
│ └── /api/puck/save/{nid} └── /api/upload/ ← Image uploads
├── Paragraph entities
└── GraphQL
Editing Flow
- Navigate to any landing page in Drupal
- Click the Design Studio tab (appears after Edit, Delete, Revisions)
- The visual editor opens with your components in the left sidebar
- Drag components onto the canvas
- Edit fields in the right panel (text, colors, images, nested items)
- Click Publish to save back to Drupal as paragraph entities
- The frontend renders the same paragraphs via GraphQL
AI Content Generation
The editor includes an AI chat panel (click the robot icon in the sidebar) that can:
| Prompt | Action |
|---|---|
| "Create a landing page for a coffee shop" | Generates a full page with hero, features, pricing, etc. |
| "Add a testimonials section with 3 reviews" | Appends a new section to the existing page |
| "Rewrite the hero with better copy" | Updates just the hero, keeping everything else |
AI is powered by puck-plugin-ai using Groq/Llama. Configure with:
GROQ_API_KEY=your_groq_api_key
GROQ_MODEL=llama-3.3-70b-versatile
UNSPLASH_ACCESS_KEY=your_unsplash_key # Optional: real images from Unsplash
Available Components
| Component | Description | Nested Items |
|---|---|---|
| Hero | Full-width header with gradient/image backgrounds, CTAs | — |
| Card Group | Feature cards in 2-4 column grid | Cards (icon, title, description) |
| Side by Side | Image + content with feature list | Feature items (icon, title) |
| Text Section | Rich text with optional CTA | — |
| Stats | Key metrics display | Stat items (value, label) |
| Testimonials | Customer quotes in grid or single | Testimonials (quote, author, rating) |
| Logo Collection | Client/partner logo grid | Logos (name, image, URL) |
| Pricing | Multi-tier pricing comparison | Pricing tiers (name, price, features) |
| Accordion / FAQ | Collapsible Q&A sections | FAQ items (question, answer) |
| Newsletter | Email signup with dark/light/gradient | — |
Manual Integration
To add the visual editor to an existing Decoupled.io project:
1. Install dependencies
npm install @puckeditor/core puck-plugin-ai
2. Enable dc_puck module in Drupal
drush en dc_puck -y
drush state:set dc_puck.editor_url "https://your-frontend.vercel.app"
3. Add puck config to your content model
Add puck keys to your components-content.json:
{
"entity": "paragraph",
"bundle": "hero",
"label": "Hero Section",
"puck": {
"name": "Hero",
"category": "hero",
"render": "ParagraphHero"
},
"fields": [
{ "id": "title", "type": "string!", "label": "Title" },
{ "id": "layout", "type": "select(centered|left-aligned)", "label": "Layout" }
]
}
4. Import content to Drupal
npm run setup-content
This auto-enables dc_puck and configures it for the landing_page content type.
5. Create the editor route
Create app/(editor)/editor/[nid]/page.tsx:
import { Puck } from '@puckeditor/core'
import { createAiChatPlugin } from 'puck-plugin-ai'
import { puckConfig } from '@/lib/puck-config'
const aiPlugin = createAiChatPlugin()
// Load data from /api/drupal-puck/load/{nid}
// Save via /api/drupal-puck/save/{nid}
// See decoupled-components for full implementation
6. Add API routes
You need these API routes:
/api/drupal-puck/[...path]— Proxy to Drupal's/api/puck/*endpoints/api/ai/generate— AI content generation (usesgeneratePuckContentfrompuck-plugin-ai/server)/api/upload— Image uploads to Cloudinary/api/auth/validate— Token validation against Drupal
See the Decoupled Components source for complete implementations.
Adding Custom Components
- Add the paragraph model with a
puckkey todata/components-content.json - Create a React component in
app/components/paragraphs/ - Add one line to
lib/component-registry.tsx - Run
npm run setup-contentto create in Drupal - Run
npm run buildto regenerate the Puck config
The Puck config auto-generates from components-content.json. Field types map automatically:
| JSON Type | Puck Field | Drupal Field |
|---|---|---|
string |
Text input | String |
text |
Textarea | Text (formatted) |
select(a|b) |
Select dropdown | List |
image |
Cloudinary upload | Image |
bool |
Radio (yes/no) | Boolean |
paragraph(type)[] |
Array field | Paragraph reference |
Drupal Module: dc_puck
The dc_puck module handles all Drupal-side integration:
- Design Studio tab — Appears on configured content types
- PuckMappingService — Auto-detects paragraph types and maps to Puck components
- Load/Save endpoints — Bidirectional paragraph ↔ Puck JSON transformation
- Token authentication — HMAC-signed tokens for secure editor access
- Config form —
/admin/config/dc-puckfor enabled types, editor URL, field mapping
Configuration
| Setting | Default | Description |
|---|---|---|
| Enabled | OFF | Master toggle for the visual editor |
| Content Types | None | Which node types show Design Studio |
| Editor URL | (required) | URL of your Puck editor app |
| Sections Field | field_sections |
Paragraph reference field name |