Using Drupal as your Gatsby Data Source

By shane
Fri, 2019-09-06 10:03
comments
Daily Dose of Drupal Episode #3

Share with Others

In this episode, we learn how to set up your Gatsby website to pull data from Drupal. We will cover:

  1. Setting up JSON:API on your Drupal site
  2. Installing the gatsby-source-drupal plugin
  3. Configuring the gatsby-source-drupal plugin
  4. Use GraphiQL to view your Drupal data
  5. Load Article nodes using gatsby-node.js
  6. Create Article Template to pull in Article data

To get started, you will need a Drupal 8 site. If you don’t have one, you can create a free Drupal 8 development site on Pantheon. Once you have your Drupal 8 site installed, make sure you have some Article content. You will also need to enable the JSON:API module.

API Module

That is it for setup on the Drupal site. The next step is to install the Gatsby Source Drupal plugin.

npm install --save gatsby-source-drupal

Or

yarn add gatsby-source-drupal

Next open the gatsby-config.js file so we can configure the plugin. Add the following code to the Gatsby config.

Gatsby Drupal Config

If you re-run your Gatsby development server, you will be able to open the GraphiQL explorer at http://localhost:8000/___graphql and explore the data the Drupal database is providing. In this case, I am filtering by the article content type. You can use the Explorer panel on the left to build the query and the play button at the top to run the query.

GraphQL Explorer

Now that you know your Gatsby site can see your Drupal data, we need to consume this data during the Gatsby build process and create pages. In this case, we want to create a page on our Gatsby site for each Article. We want to make sure we use the path that was configured in Drupal as the path to our Article. Anytime we want to create pages during the Gatsby build process, we can do so in the gatsby-node.js file. Go ahead and open that file up.

Add the following code to that file:

const path = require('path');
 
exports.createPages = async ({ actions, graphql }) => {
 const { createPage } = actions;
 
 const articles = await graphql(`
   {
     allNodeArticle {
       nodes {
         id
         title
         path {
           alias
         }
       }
     }
   }
 `);
 
 articles.data.allNodeArticle.nodes.map(articleData =>
   createPage({
     path: articleData.path.alias,
     component: path.resolve(`src/templates/article.js`),
     context: {
       ArticleId: articleData.id,
     },
   })
 );
}

This code does a few things. First it uses GraphQL to pull in the id and path of all the Articles from your Drupal site. It then loops through this list and calls Gatsby’s createPage method which will create a Gatsby page for this Article. We make sure we pass in the correct path and a template (which we still need to create). We also pass in the Article id as the context. You will see why this is important in a few minutes.

Create the src/templates folder if it doesn’t already exist, then create a file called article.js. Add the following code to this new article.js file:

import React from 'react';
import PropTypes from 'prop-types';
import { graphql } from 'gatsby';
 
import Layout from '../components/layout';
 
const Article = ({ data }) => {
 const post = data.nodeArticle;
 
 return (
   <Layout>
     <h1>{post.title}</h1>
     <img 
        src={data.nodeArticle.relationships.field_image.localFile.publicURL}
        alt={data.nodeArticle.field_image.alt}
      />
 
     <div
       dangerouslySetInnerHTML={{ __html: post.body.processed }}
     />
   </Layout>
 );
};
 
Article.propTypes = {
 data: PropTypes.object.isRequired,
};
 
export const query = graphql`
 query($ArticleId: String!) {
   nodeArticle(id: { eq: $ArticleId }) {
     id
     title
     body {
       processed
     }
     field_image {
        alt
      }
     relationships {
        field_image {
          localFile {
            publicURL
          }
        }
      }
 
   }
 }
`;
 
export default Article;

This might seem a bit confusing at first. The first section contains the React component called Article. It receives a data prop which contains Article data. It returns outputs the title and the body text in a Layout component.

The second part contains the propTypes. This just says that our Article component will receive a prop called data that will be an object and it will be required. This is just a way to validate our props.

The third part is where it gets a bit more confusing. As you already know, we ran one query in the gatsby-node.js file to get the data, but here we are also running a page query. When using Drupal as a backend, it’s useful for each template to run it’s own page query so it can build the page in a self contained manner. This is especially important when you want to implement live preview (which we will cover in the future). This query takes the id and loads additional Article data such as the title and the body field. Notice that the relationships field has to be used to pull in the actual image.

Another thing to note here is that this is not the best way to pull in images. It’s recommended to use the Gatsby Image component, but that makes the GraphQL a little more complicated so we will revisit that in more depth in the future.

If you shut down and re-run your Gatsby development server, it should create the article pages at the same path they were created on your Drupal site. There is no listing page (another thing we will fix in the future), but you can manually paste one of the known paths into the address bar to see your Article content on your Gatsby Site!

Gatsby Article Page