Decoupled Drupal 8 + GatsbyJS: a quickstart guide
Decoupled Drupal 8 + GatsbyJS: a quickstart guide
Mike Crittenden | Senior Software Architect
July 17, 2018
If you're not familiar with GatsbyJS, then you owe it to yourself to check it out. It's an up and coming static site generator with React and GraphQL baked in, and it prides itself on being really easy to integrate with common CMS'es like Drupal.
In other words, Gatsby lets you use Drupal as the backend for a completely static site. This means you get a modern frontend stack (React, GraphQL, Webpack, hot reloading, etc.) and a fully static site (with all of the performance and security benefits that come along with static sites) while still keeping the power of Drupal on the backend.
Let's give it a shot! In this post, we'll see just how simple it is to use Drupal 8 as the backend for a Gatsby-powered static site.
Step 1: Set up Drupal
This step is super easy. You basically just have to install and configure the JSON API module for Drupal 8, and you're done.
First off (assuming you already have a Drupal 8 site running), we'll just download and install the JSON API module.
composer require drupal/jsonapi drupal module:install jsonapi
Now we just have to make sure we grant anonymous users read permission on the API. To do this, go to the permissions page and check the "Anonymous users" checkbox next to the "Access JSON API resource list" permission. If you skip this step, you'll be scratching your head about the endless stream of 406 error codes.
After this you should be all set. Try visiting http://YOURSITE.com/jsonapi and you should see a list of links. For example, if you have an "Article" content type, you should see a link to http://YOURSITE.com/jsonapi/node/article, and clicking that link will show you a JSON list of all of your Article nodes.
Working? Good. Let's keep moving.
Step 2: Install GatsbyJS
Now we need to work on Gatsby. If you don't have it installed already, run this to grab it:
npm install --global gatsby-cli
That'll give you the "gatsby" cli tool, which you can then use to create a new project, like so:
gatsby new YOURSITENAME
That command basically just clones the default Gatsby starter repo, and then installs its dependencies inside it. Note that you can include another parameter on that command which tells Gatsby that you want to use one of the starter repos, but to keep things simple we'll stick with the default.
Once complete, you have the basis for a working Gatsby site. But that's not good enough for us! We need to tell Gatsby about Drupal first.
Step 3: Tell Gatsby about Drupal
For this part, we'll be using the gatsby-source-drupal plugin for Gatsby. First, we need to install it:
cd YOURSITENAME npm install --save gatsby-source-drupal
Once that's done, we just need to add a tiny bit of configuration for it, so that Gatsby knows the URL of our Drupal site. To do this, edit the gatsby-config.js file and add this little snippet to the "plugins" section:
plugins: [ { resolve: `gatsby-source-drupal`, options: { baseUrl: `http://YOURSITE.COM`, }, }, ]
You're all set. That's all the setup that's needed, and now we're ready to run Gatsby and have it consume Drupal data.
Step 4: Run Gatsby
Let's kick the tires! Run this to get Gatsby running:
gatsby develop
If all goes well, you should see some output like this:
You can now view gatsby-starter-default in the browser. http://localhost:8000/ View GraphiQL, an in-browser IDE, to explore your site's data and schema http://localhost:8000/___graphql Note that the development build is not optimized. To create a production build, use gatsby build
(If you see an error message instead, there's a good chance your Drupal site isn't set up correctly and is erroring. Try manually running "curl yoursite.com/jsonapi" in that case to see if Drupal is throwing an error when Gatsby tries to query it.)
You can load http://localhost:8000/ but you won't see anything particularly interesting yet. It'll just be a default Gatsby starter page. It's more interesting to visit the GraphQL browser and start querying Drupal data, so let's do that.
Step 5: Fetching data from Drupal with GraphQL
Load up http://localhost:8000/___graphql in a browser and you should see a GraphQL UI called GraphiQL (pronounced "graphical") with cool stuff like autocomplete of field names and a schema explorer.
Clear out everything on the left side, and type an opening curly bracket. It should auto-insert the closing one for you. Then you can hit ctrl+space to see the autocomplete, which should give you a list of all of the possible Drupal entity types and bundles that you can query. It should look something like this:
For example, if you want to query Event nodes, you'll enter "allNodeEvent" there, and drill down into that object.
Here's an example which grabs the "title" of the Event nodes on your Drupal site:
{ allNodeEvent { edges { node { title } } } }
Note that "edges" and "node" are concepts from Relay, the GraphQL library that Gatsby uses under the hood. If you think of your data like a graph of dots with connections between them, then the dots in the graph are called “nodes” and the lines connecting them are called “edges.” You don't need to worry about this at the moment. For now, just get used to typing it.
Once you have that snippet written, you can click the play icon button at the top to run it, and you should see a result like this on the right side:
{ "data": { "allNodeEvent": { "edges": [ { "node": { "title": "Test node 1" } }, { "node": { "title": "Test node 2" } }, { "node": { "title": "Test node 3" } } ] } } }
Note that this same pattern can give you pretty much any data you want from Drupal, including entity reference field data or media image URIs, etc. As a random example, here's a snippet from the Contenta CMS + GatsbyJS demo site:
{ allNodeRecipe { edges { node { title preparationTime difficulty totalTime ingredients instructions relationships { category { name } image { relationships { imageFile { localFile { childImageSharp { fluid(maxWidth: 470, maxHeight: 353) { ...GatsbyImageSharpFluid } } } } } } } } } } }
Pretty cool right? Everything you need from Drupal, in one GraphQL query.
So now we have Gatsby and Drupal all set up and we know how to grab data from Drupal, but we haven't actually changed anything on the Gatsby site yet. Let's fix that.
Step 6: Displaying Drupal data on the Gatsby site
The cool thing about Gatsby is that GraphQL is so baked in that it assumes that you'll be writing GraphQL queries directly into the components/templates.
In your codebase, check out src/pages/index.js and you should see some placeholder content. Delete everything in there, and replace it with this:
import React from 'react' class IndexPage extends React.Component { render() { const pages = this.props.data.allNodePage.edges const pageTitles = pages.map(page => <li>{page.node.title}</li>) return <ul>{pageTitles}</ul> } } export default IndexPage export const query = graphql` query pageQuery { allNodePage { edges { node { title } } } } `
(Note, this assumes you have a node type named "Page").
All we're doing here is grabbing the node titles via the GraphQL query at the bottom, and then displaying them in a bulleted list.
Here's how that looks on the frontend:
And that's it! We are displaying Drupal data on our Gatsby site!
Step 7: Moving on
From here, you'll probably want to look at more complex stuff like creating individual pages in Gatsby for each Drupal node, or displaying more complicated data, or resizing Drupal images, etc. Go to it! The static site is your oyster!
When you're happy with it, just run "gatsby build" and it'll export an actual static site that you can deploy anywhere you want, like Github Pages or Amazon S3 or Netlify.
Have fun!