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_puck module
  • Configures the visual editor for landing_page content 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

  1. Navigate to any landing page in Drupal
  2. Click the Design Studio tab (appears after Edit, Delete, Revisions)
  3. The visual editor opens with your components in the left sidebar
  4. Drag components onto the canvas
  5. Edit fields in the right panel (text, colors, images, nested items)
  6. Click Publish to save back to Drupal as paragraph entities
  7. 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 (uses generatePuckContent from puck-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

  1. Add the paragraph model with a puck key to data/components-content.json
  2. Create a React component in app/components/paragraphs/
  3. Add one line to lib/component-registry.tsx
  4. Run npm run setup-content to create in Drupal
  5. Run npm run build to 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-puck for 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

Resources