Headless Drupal with Next.js: A Practical Architecture Guide
How to architect a decoupled Drupal backend with a Next.js frontend — covering JSON:API, authentication, content modeling, and deployment strategies.
The Case for Decoupled Drupal
Decoupled (headless) Drupal separates the content management backend from the frontend presentation layer. This architecture enables teams to use modern JavaScript frameworks like Next.js for the frontend while leveraging Drupal's powerful content modeling and editorial tools.
Setting Up JSON:API
Drupal's JSON:API module (included in core since Drupal 9) provides a standards-compliant API out of the box. Enable it and configure your resource types:
// Enable JSON:API in your .install file
function my_module_install() {
\Drupal::service('module_installer')->install(['jsonapi']);
}
JSON:API automatically exposes all entity types with full CRUD operations, filtering, sorting, pagination, and relationship inclusion.
Content Modeling for API Consumption
When designing content types for a headless setup, think about the API consumer's needs. Structure your entities with clear relationships and avoid deeply nested references that create N+1 query patterns.
Key principles:
- Flat over nested: Keep reference depth to 2 levels maximum
- Computed fields: Use computed field plugins for derived data
- Entity references: Prefer entity references over free text for structured data
- Media entities: Always use Media for images and files (better API representation)
Authentication Strategy
For public content, JSON:API works without authentication. For protected resources, implement OAuth2 using the Simple OAuth module:
# Configure OAuth2 scopes
simple_oauth.settings:
access_token_expiration: 3600
refresh_token_expiration: 1209600
Next.js Data Fetching
On the Next.js side, fetch data at build time using generateStaticParams and fetch with ISR (Incremental Static Regeneration):
async function getArticles() {
const res = await fetch(
`${process.env.DRUPAL_BASE_URL}/jsonapi/node/article?sort=-created&page[limit]=10`,
{ next: { revalidate: 60 } }
);
return res.json();
}
Caching Strategy
The decoupled architecture needs a solid caching strategy:
- CDN layer: Cache JSON:API responses at the edge
- Drupal cache tags: Enable cache tag headers for targeted invalidation
- Next.js ISR: Revalidate pages on a schedule or on-demand via webhooks
- Webhook integration: Drupal fires webhooks on content changes, Next.js revalidates affected paths
Deployment Architecture
The recommended deployment setup:
- Drupal: Hosted on a traditional LAMP/Docker stack
- Next.js: Deployed on Vercel or similar edge platform
- CDN: Between Drupal and Next.js for API caching
- Webhook relay: Content changes trigger Next.js revalidation
Conclusion
Headless Drupal with Next.js gives you the best of both worlds: Drupal's mature content management and editorial experience paired with Next.js's performance and developer experience for the frontend.