Decoupled Drupal with Gatsby

Decoupled Drupal with Gatsby

In this post, i share my experience for developpement webstite with Drupal 8  and Gatsby.Gatsby let use web service rest Drupal for a completely static site. 

Requirement Drupal 

Enable and configure the JSON:API module.

drupal

Check the result JSON for nodes (Example : of type article http://localhost:8181/jsonapi/node/article). 

Gatsby & Data from Drupal

You need to install Gtasby CLI : npm install --global gatsby-cli

Create new project with the gatsby cli : gatsby new SITENAME

For more instructions at https://www.gatsbyjs.org/docs/quick-start.

You need to install the plugin gatsby-source-drupal to pull data from Drupal via JSON:API.

In the project directory : npm install --save gatsby-source-drupal

// In your gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-drupal`,
      options: {
        baseUrl: `https://localhost:8181/`,
      },
    },
  ],
}

Then run Gatsby : gatsby develop

drupal

Explore data from Drupal with Graphql

Visit http://localhost:8000/___graphql to see data from drupal and the query schema using by GraphiQL.

drupal

Create pages on Gatsby

To create page list of article pages/list.js

{ data.allNodeArticle.edges.map(({ node }, i) => (
    <div className="detail-post">
         <Link style={{ boxShadow: 'none' }} to={node.fields.slug}>
        <h1>{ node.title }</h1>
        <time dateTime={ node.changed }>{ node.changed }</time>
        </Link>
        <div className="content text-justify"><div dangerouslySetInnerHTML={{ __html: node.fields.intro }} /></div>
     </div> 
))}

Let create pages for each of our articles. Add the following code in gatsby-node.js

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if(Object.keys(node).length > 0){
    const title = `/post/${node.title}/`
    const slug = title.replace(/ /g,'-')
    const body = node.body != undefined ? node.body.value : ''
    const intro = body.length > 0 ? body.substring(0, 150)+`...` : '' 
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    }
    )
    createNodeField(
      {
        node,
        name: `intro`,
        value: intro,
      }
    )
  } 
}

const ArticleTemplate = path.resolve('./src/templates/Article/index.js')
exports.createPages = ({ actions, graphql }) => {
  const { createPage } = actions
  return graphql(
    `
      {
        allNodeArticle {
          edges {
            node {
              id
              drupal_id
              changed (formatString: "DD MMMM YYYY")
              title
              body {
                value
              }
              fields {
                slug,
                intro
              }
            }
          }
        }
      }
    `
  ).then(result => {
    if (result.errors) {
      throw result.errors
    }

    // Create pages for each article.
    result.data.allNodeArticle.edges.forEach(({ node }) => {
      createPage({
        path: node.fields.slug,
        component: ArticleTemplate,
        context: {
          slug: node.fields.slug,
        },
      })
    })
  })
}

Then the following code in src/templates/Article/index.js

import React from 'react'
import { graphql } from 'gatsby'
import Layout from 'components/Layout'

const Article = ({data, location}) => (
  <Layout location={location}>
    <div className="article" >
      <div className="container">
        <div className="row">
            <div className="col-md-12 ">
              {data != null &&
                  <div>
                      <h1>{ data.nodeArticle.title }</h1>
                      <time dateTime={ data.nodeArticle.changed }>{ data.nodeArticle.changed }</time>
                      <div className="content"><div dangerouslySetInnerHTML={{ __html: data.nodeArticle.body.value }} /></div>
                  </div>
              }
            </div>
           </div>
        </div>
    </div>
  </Layout> )

export default Article

export const pagedetail = graphql`
  query detailPost ($slug: String!) {
    nodeArticle (fields: { slug: { eq: $slug } }) {
          id
          drupal_id
          changed (formatString: "DD MMMM YYYY")
          title
          body {
            value
          }
          fields {
            slug
          }
        }
  }
`

 

Conclusion

At the end, you can run gatsby bulid and deploy the website to anywhere https://www.gatsbyjs.org/docs/deploying-and-hosting.

You can see more in https://www.gatsbyjs.com/guides/drupal.

Comments