Code Examples

Examples & Templates

Content models, import templates, and Next.js integration patterns you can use right away.

Blog

Content Import JSON

Use this with npx decoupled-cli@latest content import --file blog.json or the MCP import_content tool.

blog.json
{
  "model": [
    {
      "bundle": "blog_post",
      "label": "Blog Post",
      "body": true,
      "fields": [
        { "id": "category", "label": "Category", "type": "string" },
        { "id": "author_name", "label": "Author", "type": "string" },
        { "id": "featured", "label": "Featured", "type": "bool" },
        { "id": "summary", "label": "Summary", "type": "string" }
      ]
    }
  ],
  "content": [
    {
      "id": "post-1",
      "type": "node.blog_post",
      "path": "/blog/getting-started-with-headless-drupal",
      "values": {
        "title": "Getting Started with Headless Drupal",
        "body": "<p>Learn how to build modern web apps with a headless CMS.</p>",
        "category": "Tutorial",
        "author_name": "Jane Developer",
        "featured": true,
        "summary": "A beginner-friendly guide to headless Drupal architecture."
      }
    },
    {
      "id": "post-2",
      "type": "node.blog_post",
      "path": "/blog/graphql-vs-json-api",
      "values": {
        "title": "GraphQL vs JSON:API - Which to Choose?",
        "body": "<p>Compare the two API approaches for your Next.js frontend.</p>",
        "category": "Architecture",
        "author_name": "John Engineer",
        "featured": false,
        "summary": "A practical comparison of GraphQL and JSON:API for decoupled Drupal."
      }
    }
  ]
}

Next.js Integration

app/blog/page.tsx
async function getPosts() {
  const res = await fetch(
    process.env.NEXT_PUBLIC_DRUPAL_BASE_URL + '/jsonapi/node/blog_post?sort=-created',
    { next: { revalidate: 60 } }
  );
  const data = await res.json();
  return data.data;
}

export default async function BlogPage() {
  const posts = await getPosts();
  return (
    <div className="max-w-3xl mx-auto py-12">
      <h1 className="text-4xl font-bold mb-8">Blog</h1>
      {posts.map((post: any) => (
        <article key={post.id} className="mb-8 border-b pb-8">
          <h2 className="text-2xl font-semibold">
            {post.attributes.title}
          </h2>
          <p className="text-gray-600 mt-2">
            {post.attributes.field_summary}
          </p>
          <span className="text-sm text-blue-600">
            {post.attributes.field_category}
          </span>
        </article>
      ))}
    </div>
  );
}

Portfolio

Content Import JSON

portfolio.json
{
  "model": [
    {
      "bundle": "project",
      "label": "Project",
      "body": true,
      "fields": [
        { "id": "client", "label": "Client", "type": "string" },
        { "id": "tech_stack", "label": "Tech Stack", "type": "string" },
        { "id": "project_url", "label": "Project URL", "type": "string" },
        { "id": "year", "label": "Year", "type": "string" }
      ]
    },
    {
      "bundle": "testimonial",
      "label": "Testimonial",
      "body": true,
      "fields": [
        { "id": "author_name", "label": "Author", "type": "string" },
        { "id": "company", "label": "Company", "type": "string" },
        { "id": "role", "label": "Role", "type": "string" }
      ]
    }
  ],
  "content": [
    {
      "id": "project-1",
      "type": "node.project",
      "path": "/projects/ecommerce-redesign",
      "values": {
        "title": "E-Commerce Platform Redesign",
        "body": "<p>Complete frontend overhaul using Next.js and headless Drupal.</p>",
        "client": "Acme Corp",
        "tech_stack": "Next.js, Drupal, GraphQL, Tailwind",
        "project_url": "https://example.com",
        "year": "2025"
      }
    },
    {
      "id": "testimonial-1",
      "type": "node.testimonial",
      "path": "/testimonials/acme",
      "values": {
        "title": "Acme Corp Testimonial",
        "body": "<p>Working with this team transformed our digital presence.</p>",
        "author_name": "Sarah Chen",
        "company": "Acme Corp",
        "role": "VP of Engineering"
      }
    }
  ]
}

E-Commerce Catalog

Content Import JSON

products.json
{
  "model": [
    {
      "bundle": "product",
      "label": "Product",
      "body": true,
      "fields": [
        { "id": "price", "label": "Price", "type": "string" },
        { "id": "sku", "label": "SKU", "type": "string" },
        { "id": "category", "label": "Category", "type": "string" },
        { "id": "in_stock", "label": "In Stock", "type": "bool" }
      ]
    }
  ],
  "content": [
    {
      "id": "product-1",
      "type": "node.product",
      "path": "/products/wireless-headphones",
      "values": {
        "title": "Wireless Headphones Pro",
        "body": "<p>Premium noise-cancelling wireless headphones.</p>",
        "price": "$299.99",
        "sku": "WHP-001",
        "category": "Audio",
        "in_stock": true
      }
    },
    {
      "id": "product-2",
      "type": "node.product",
      "path": "/products/mechanical-keyboard",
      "values": {
        "title": "Mechanical Keyboard",
        "body": "<p>Cherry MX switches with RGB backlighting.</p>",
        "price": "$149.99",
        "sku": "MKB-002",
        "category": "Peripherals",
        "in_stock": true
      }
    }
  ]
}

MCP Workflow Examples

These are example prompts you can give to your AI assistant when connected via MCP.

Full site setup

"Create a new Drupal space called 'Recipe Blog', import a recipe content
type with fields for ingredients, cook time, difficulty, and servings.
Add 5 sample recipes. Then get me the OAuth credentials so I can connect
my Next.js frontend."

Usage audit

"List all my spaces, show usage stats for each one, and tell me which
ones are using the most storage and bandwidth."

Staging environment

"Clone space 42 as 'Staging - Feature Test', get me a login link for the
new space, and show me the GraphQL endpoint URL."