Drupal + Gatsby

Gatsby’s Drupal source plugin now supports multilingual websites out of the box

By Robert Caracaus · 21st of September, 2021

Recently our team at Desarol migrated a large Drupal 7 website for a multinational hotel chain to a decoupled Drupal 9 back-end with a Gatsby front-end. First-class support for localization into Spanish was a key requirement to support the client’s many guests visiting South American locations.

Unfortunately, during the discovery phase we found that the default gatsby-source-drupal source plugin only downloaded content written in English (or whatever language was selected  as Drupal’s default language). There was no clear path to simultaneously source content written in Spanish, so we submitted a pull request to Gatsby to allow this functionality.

Thanks to review and collaboration from Gatsby’s core team and the Drupal community, our feature branch has been merged which addresses this issue and brings translation support into Gatsby’s core source plugin. Setting up a fully translatable Gatsby site with Drupal 8 or 9 is now as easy as enabling one core Drupal module (JSON:API) and installing and configuring the source plugin on the Gatsby side.

Generating language specific pages

Once you have the different content translations showing up inside of Gatsby’s GraphQL database you can select the language you would like to use in a page template by filtering based on the language code. You will want to feed the language code for that page into the query using page context.

const path = require('path')

const prefixAliasWithLanguage = (alias, langcode = 'en') => (
  langcode === 'en'
  ? alias
  : `/${langcode}${alias}`
)

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const BlogTemplate = path.resolve('src/templates/Blog.tsx')
  const queryResult = await graphql(`
    {
      allNodeBlog {
        nodes {
          drupal_internal__nid
          langcode
          path { alias }
        }
      }
    } 
  `)

  if (queryResult.errors) {
    throw queryResult.errors
  }

  queryResult.data.allNodeBlog.nodes.forEach((node) => { 
    createPage({
      path: prefixAliasWithLanguage(node.path.alias, node.langcode), 
      component: BlogTemplate,
      context: {
        drupal_internal__nid: node.drupal_internal__nid,
        langcode: node.langcode
      },
    })
  })
}
query ($drupal_internal__nid: Int, $langcode: String) {
  nodeBlog(
    drupal_internal__nid: {eq: $drupal_internal__nid},
    langcode: {eq: $langcode}
  ) {
    drupal_internal__nid
    title
    path { alias }
  }
}

Letting the user choose a language with React

Now that the pages have been created all that’s left to do is create a link between the two translations so that users can switch between them. By following a structured URL pattern similar to the Drupal side we are able to create a link to the Spanish translation from the English translation and vice-versa. Coming back to the previous example, so long as you fetch the path for the current language and all alternative translations you will have a way to provide the user a link to that content via a dropdown or something similar.

query blogQuery($drupal_internal__nid: Int!) {
  english: nodeBlog(
    drupal_internal__nid: { eq: $drupal_internal__nid },
    langcode: { eq: "en" }
  ) {
    path {
      alias
    }
  }
  spanish: nodeBlog(
    drupal_internal__nid: { eq: $drupal_internal__nid },
    langcode: { eq: "es" }
  ) {
    path {
      alias
    }
  }

  # ... the rest of your query 
}
<a href={english.path.alias}>English</a>
<a href={spanish.path.alias}>Spanish</a>

Optimizing translations for search engines

Make sure you remember to leverage react-helmet to include metatags (eg. lang and hreflang) which document the language your page is written in. You can read more on these here but long story short you should include them for the best chance of getting your article in front of your audience in the right language.

Looking forward towards an even closer relationship between Gatsby and Drupal

Following the drive towards core support for internationalization in Drupal it’s amazing to see Gatsby take full advantage and leverage everything the latest versions have to offer. Desarol is excited to keep working in collaboration with the Gatsby team to bring even more power to the Gatsby + Drupal integration. For instance there’s some upcoming work to make downloading content even faster, so stay tuned!