Building Headless Drupal Applications with Druvance
A complete guide to decoupled Drupal architecture using JSON:API and modern frontend frameworks.
Building Headless Drupal Applications with Druvance
Headless Drupal (or decoupled Drupal) separates the content management backend from the frontend presentation layer. This approach offers flexibility, performance, and modern development workflows.
What is Headless Drupal?
Traditional Drupal:
- Backend and frontend tightly coupled
- Drupal renders HTML
- Limited frontend flexibility
Headless Drupal:
- Backend serves content via API
- Frontend is a separate application
- Use any frontend technology
Why Go Headless?
Benefits
- **Frontend Freedom** - Use React, Vue, Next.js, or any framework
- **Better Performance** - Static site generation, client-side routing
- **Omnichannel** - Serve content to web, mobile, IoT, etc.
- **Developer Experience** - Modern tooling and workflows
Trade-offs
- **Complexity** - Two systems to maintain
- **Preview Challenges** - Content preview requires additional setup
- **Module Compatibility** - Some Drupal modules won't work
Getting Started
Enable JSON:API
JSON:API is included in Drupal core:
# Enable the module
drush en jsonapi
# Verify it's working
curl https://yoursite.druvance.com/jsonapiConfigure CORS
Allow your frontend to access the API:
# services.yml
parameters:
cors.config:
enabled: true
allowedOrigins: ['https://yourfrontend.com']
allowedMethods: ['GET', 'POST', 'PATCH', 'DELETE']
allowedHeaders: ['*']Building the Frontend
Next.js Example
Create a modern React frontend:
// lib/drupal.ts
const DRUPAL_URL = process.env.NEXT_PUBLIC_DRUPAL_URL;
export async function getArticles() {
const res = await fetch(`${DRUPAL_URL}/jsonapi/node/article`);
return res.json();
}
// pages/index.tsx
export default function Home({ articles }) {
return (
<div>
<h1>Latest Articles</h1>
{articles.data.map(article => (
<article key={article.id}>
<h2>{article.attributes.title}</h2>
<p>{article.attributes.body.value}</p>
</article>
))}
</div>
);
}
export async function getStaticProps() {
const articles = await getArticles();
return { props: { articles } };
}Authentication
For protected content, use OAuth:
// Get access token
const token = await fetch(`${DRUPAL_URL}/oauth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'password',
client_id: 'your-client-id',
username: 'user',
password: 'pass',
}),
});
// Use token in requests
const articles = await fetch(`${DRUPAL_URL}/jsonapi/node/article`, {
headers: {
'Authorization': `Bearer ${token.access_token}`,
},
});Content Modeling
Structured Content
Design content types for API consumption:
Article
├── Title (text)
├── Body (formatted text)
├── Author (entity reference)
├── Tags (taxonomy)
├── Featured Image (media)
└── Published Date (datetime)Custom Fields
Create API-friendly field types:
// Custom field formatter
namespace DrupalmymodulePluginFieldFieldFormatter;
use DrupalCoreFieldFormatterBase;
/**
* @FieldFormatter(
* id = "api_image_formatter",
* label = @Translation("API Image Formatter"),
* field_types = {"image"}
* )
*/
class ApiImageFormatter extends FormatterBase {
public function viewElements($items, $langcode) {
$elements = [];
foreach ($items as $delta => $item) {
$elements[$delta] = [
'url' => $item->entity->createFileUrl(),
'alt' => $item->alt,
'width' => $item->width,
'height' => $item->height,
];
}
return $elements;
}
}Advanced Patterns
Incremental Static Regeneration
Keep content fresh with ISR:
// Next.js ISR
export async function getStaticProps() {
const articles = await getArticles();
return {
props: { articles },
revalidate: 60, // Regenerate every 60 seconds
};
}On-demand Revalidation
Trigger rebuilds when content changes:
// Drupal module
function mymodule_node_update($node) {
// Call frontend revalidation endpoint
Drupal::httpClient()->post(
'https://frontend.com/api/revalidate',
['json' => ['path' => '/node/' . $node->id()]]
);
}GraphQL Alternative
For complex queries, consider GraphQL:
# Install GraphQL module
composer require drupal/graphql
# Example query
query {
articles(limit: 10) {
title
author {
name
picture
}
tags
published
}
}Performance Optimization
CDN Caching
Cache API responses at the edge:
# Cloudflare Page Rule
URL: */jsonapi/*
Cache Level: Cache Everything
Edge Cache TTL: 1 hourResponse Optimization
Use sparse fieldsets to reduce payload:
# Only get the fields you need
/jsonapi/node/article?fields[node--article]=title,bodyPagination
Handle large result sets:
# Paginated requests
/jsonapi/node/article?page[limit]=10&page[offset]=0
/jsonapi/node/article?page[limit]=10&page[offset]=10Deployment on Druvance
Multi-site Setup
Deploy frontend and backend together:
druvance.yml
sites:
backend:
type: drupal
docroot: backend/web
frontend:
type: node
docroot: frontend
build: npm run build
start: npm startEnvironment Variables
Configure different environments:
# .env.development
NEXT_PUBLIC_DRUPAL_URL=https://backend.druvance.dev
# .env.production
NEXT_PUBLIC_DRUPAL_URL=https://backend.druvance.comCommon Challenges
Preview Mode
Implement content preview:
// Preview API route
export default async function handler(req, res) {
const { slug, token } = req.query;
// Verify preview token
const previewData = await verifyToken(token);
// Fetch draft content
const article = await getDraftArticle(slug, previewData);
res.setPreviewData(previewData);
res.redirect(`/articles/${slug}`);
}SEO
Handle SEO in headless architecture:
- Use Next.js for server-side rendering
- Implement meta tags dynamically
- Generate sitemaps from Drupal content
- Handle redirects in frontend
Conclusion
Headless Drupal offers powerful flexibility for modern web applications. With Druvance's support for both Drupal and Node.js applications, building decoupled architectures has never been easier.
Ready to go headless? [Start your free trial today.](https://druvance.com/signup)
Written by Alex Rivera
Senior Frontend Developer
Alex Rivera is part of the Druvance team, helping developers and organizations build better Drupal experiences. Follow for more insights on Drupal, web development, and cloud hosting.
Related Articles
Getting Started with Druvance: A Complete Guide for Beginners
Learn how to set up your first Drupal site on Druvance in under 10 minutes. This comprehensive guide covers everything from account creation to going live.
How AI is Revolutionizing Drupal Performance Optimization
Discover how Druvance uses artificial intelligence to automatically optimize your Drupal sites for peak performance.
Subscribe to our newsletter
Get the latest articles, tutorials, and updates delivered to your inbox.