Next.js 14, Drupal 11 and App Router Support
The future of Drupal is headless
Next.js for Drupal has everything you need to build a next-generation front-end for your Drupal site.
Everything you expect from Drupal.
On a modern stack.
Go headless without compromising features.
Seamless Editing
Inline preview built-in to the editing interface.
Instant Publishing
New content and updates are live instantly.
Multi-site
Power multiple Next.js sites from one Drupal site.
Authentication
Authentication with support for roles and permissions.
Webforms
Built React forms backed by the Webform module.
Search API
Support for decoupled faceted search powered by Search API.
Internationalization
Built-in translation and Automatic Language detection.
Performance
Deploy and scale your sites via content delivery networks.
Security
Protect your site from attacks by separating code from the interface.
Out-of-the-box tooling for the best developer experience
A powerful client for working with JSON:API.
// Create a DrupalClient.
const drupal = new DrupalClient("http://drupal.org", {
auth: {} // Authentication
fetcher: {} // Custom fetcher
cache: {} // Cache support
serializer: {} // Custom serializer
})
// Fetch an article.
const article = await drupal.getResource(
"node--article",
"907034d4-ab35-4949-84e4-d2b7afed82df"
)
// Create an article
const article = await drupal.createResource("node--article", {
attributes: {
title: "Title of Article",
body: {
value: "<p>Content of body field</p>",
format: "full_html",
},
},
})
// Fetch an article.
const article = await drupal.getResource(
"node--article",
"907034d4-ab35-4949-84e4-d2b7afed82df"
)
// Fetch a collection of terms.
const tags = await drupal.getResourceCollection("taxonomy_term--tags")
// Fetch a menu.
const main = await drupal.getMenu("main")
// Fetch a view.
const recentContent = await drupal.getView("content_recent--block")
// Use filters.
const sortedPublishArticles = await drupal.getResourceCollection(
"node--article",
{
params: {
"filter[status]": "1",
sorted: "-created",
},
}
)
// Create an article.
const article = await drupal.createResource("node--article", {
attributes: {
title: "Title of Article",
body: {
value: "<p>Content of body field</p>",
format: "full_html",
},
},
})
// Update article.
const article = await drupal.updateResource(
"node--article",
"a937dd34-5407-4fff-8594-fccaaa5bb72a",
{
data: {
attributes: {
title: "Title of Article",
},
},
}
)
// Delete article.
const deleted = await drupal.deleteResource(
"node--article",
"a937dd34-5407-4fff-8594-fccaaa5bb72a"
)
// Get the `es` translation for a page by uuid.
const page = await drupal.getResource(
"node--page",
"07464e9f-9221-4a4f-b7f2-01389408e6c8",
{
locale: "es",
defaultLocale: "en",
}
)
// Fetch a collection of translated articles.
const articles = await drupal.getResourceCollection("node--article", {
locale: "es",
defaultLocale: "en",
})
// Fetch translated menu items.
const main = await drupal.getMenu("main", {
locale: "es",
defaultLocale: "en",
})
// Bearer token.
export const drupal = new DrupalClient(
process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,
{
auth: {
clientId: process.env.DRUPAL_CLIENT_ID,
clientSecret: process.env.DRUPAL_CLIENT_SECRET,
},
}
)
// Basic.
export const drupal = new DrupalClient(
process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,
{
auth: {
username: process.env.DRUPAL_USERNAME,
password: process.env.DRUPAL_PASSWORD,
},
}
)
// Bring your own.
export const drupal = new DrupalClient(
process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,
{
auth: () => {
// Do something and return an Authorization header.
},
}
)
// DrupalNode
const article = await drupal.getResource<DrupalNode>(
"node--article",
"907034d4-ab35-4949-84e4-d2b7afed82df"
)
// DrupalTaxonomyTerm
const tags = await drupal.getResourceCollection<DrupalTaxonomyTerm[]>(
"taxonomy_term--tags"
)
// Any resource type.
const resources =
await drupal.getResourceCollection<JsonApiResource[]>("entity--bundle")
const data = await query({
query: `
query {
nodeArticles(first: 10) {
nodes {
id
title
path
author {
displayName
}
body {
processed
}
created
image {
width
url
height
}
}
}
}
`,
})