Skip to content

Drupal & Astro

Add content to your Astro project using Drupal as a CMS

Drupal is an open-source content management tool.

To get started, you will need to have the following:

  1. An Astro project - If you don’t have an Astro project yet, our Installation guide will get you up and running in no time.

  2. A Drupal site - If you haven’t set up a Drupal site, you can follow the official guidelines Installing Drupal.

To be able to get content from Drupal you need to enable the Drupal JSON:API module.

  1. Navigate to the Extend page admin/modules via the Manage administrative menu
  2. Locate the JSON:API module and check the box next to it
  3. Click Install to install the new module

Now you can make GET requests to your Drupal application through JSON:API.

To add your Drupal URL to Astro, create a .env file in the root of your project (if one does not already exist) and add the following variable:

.env
DRUPAL_BASE_URL="https://drupal.ddev.site/"

Restart the dev server to use this environment variable in your Astro project.

By default, the Drupal JSON:API endpoint is accessible for external data-fetching requests without requiring authentication. This allows you to fetch data for your Astro project without credentials but it does not permit users to modify your data or site settings.

However, if you wish to restrict access and require authentication, Drupal provides several authentication methods including:

You can add your credentials to your .env file.

.env
DRUPAL_BASIC_USERNAME="editor"
DRUPAL_BASIC_PASSWORD="editor"
DRUPAL_JWT_TOKEN="abc123"
...

Your root directory should now include this new files:

JSON:API requests and responses can often be complex and deeply nested. To simplify working with them, you can use two npm packages that streamline both the requests and the handling of responses:

  • JSONA: JSON API v1.0 specification serializer and deserializer for use on the server and in the browser.
  • Drupal JSON-API Params: This module provides a helper Class to create the required query. While doing so, it also tries to optimise the query by using the short form, whenever possible.

Your content is fetched from a JSON:API URL.

The basic URL structure is: /jsonapi/{entity_type_id}/{bundle_id}

The URL is always prefixed by jsonapi.

  • The entity_type_id refers to the Entity Type, such as node, block, user, etc.
  • The bundle_id refers to the Entity Bundles. In the case of a Node entity type, the bundle could be article.
  • In this case, to get the list of all articles, the URL will be [DRUPAL_BASE_URL]/jsonapi/node/article.

To retrieve an individual entity, the URL structure will be /jsonapi/{entity_type_id}/{bundle_id}/{uuid}, where the uuid is the UUID of the entity. For example the URL to get a specific article will be of the form /jsonapi/node/article/2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e.

Retrieve only certain field by adding the Query String field to the request.

GET: /jsonapi/{entity_type_id}/{bundle_id}?field[entity_type]=field_list

Examples:

  • /jsonapi/node/article?fields[node--article]=title,created
  • /jsonapi/node/article/2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e?fields[node--article]=title,created,body

Add a filter to your request by adding the filter Query String.

The simplest, most common filter is a key-value filter:

GET: /jsonapi/{entity_type_id}/{bundle_id}?filter[field_name]=value&filter[field_other]=value

Examples:

  • /jsonapi/node/article?filter[title]=Testing JSON:API&filter[status]=1
  • /jsonapi/node/article/2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e?fields[node--article]=title&filter[title]=Testing JSON:API

You can find more query options in the JSON:API Documentation.

Astro components can fetch data from your Drupal site by using drupal-jsonapi-params package to build the query.

The following example shows a component with a query for an “article” content type that has a text field for a title and a rich text field for content:

---
import {Jsona} from "jsona";
import {DrupalJsonApiParams} from "drupal-jsonapi-params";
import type {TJsonApiBody} from "jsona/lib/JsonaTypes";
// Get the Drupal base URL
export const baseUrl: string = import.meta.env.DRUPAL_BASE_URL;
// Generate the JSON:API Query. Get all title and body from published articles.
const params: DrupalJsonApiParams = new DrupalJsonApiParams();
params.addFields("node--article", [
"title",
"body",
])
.addFilter("status", "1");
// Generates the query string.
const path: string = params.getQueryString();
const url: string = baseUrl + '/jsonapi/node/article?' + path;
// Get the articles
const request: Response = await fetch(url);
const json: string | TJsonApiBody = await request.json();
// Initiate Jsona.
const dataFormatter: Jsona = new Jsona();
// Deserialise the response.
const articles = dataFormatter.deserialize(json);
---
<body>
{articles?.length ? articles.map((article: any) => (
<section>
<h2>{article.title}</h2>
<article set:html={article.body.value}></article>
</section>
)): <div><h1>No Content found</h1></div> }
</body>

You can find more querying options in the Drupal JSON:API Documentation

With the setup above, you are now able to create a blog that uses Drupal as the CMS.

  1. An Astro project with JSONA and Drupal JSON-API Params installed.

  2. A Drupal site with at least one entry - For this tutorial we recommend starting with a new Drupal site with Standard installation.

    In the Content section of your Drupal site, create a new entry by clicking the Add button. Then, choose Article and fill in the fields:

    • Title: My first article for Astro!
    • Alias: /articles/first-article-for astro
    • Description: This is my first Astro article! Let's see what it will look like!

    Click Save to create your first Article. Feel free to add as many articles as you want.

Use the same method to fetch your data from Drupal as above, but this time, on a page that will create a unique page route for each article.

This example uses Astro’s default static mode, and creates a dynamic routing page file with the getStaticPaths() function. This function will be called at build time to generate the list of paths that become pages.

To deploy your website, visit our deployment guides and follow the instructions for your preferred hosting provider.