Optimising Gatsby with Drupal
We’ve been building a site with Gatsby connected to our Drupal 8 CMS using gatsby-drupal-source
. The site has a section for logged in users only, which makes requests to an API served by our Drupal site to deliver a suite of products based on the logged in user’s subscription. The rest of the site and page templates are generated at build time.
The collection includes over 1000 products, and we have about 3400 uploaded files. Because the only way we’re serving this content is via our API which are hit on client-only routes, we want Gatsby to ignore this content unless it’s necessary for building the static site pages. Otherwise we’ll be generating schema, downloading files and creating thumbnails for a lot of nodes that we’ll never use.
So, to ensure that we’re only pulling the content we need at build time, we can setup disallowedLinkTypes
:
Now, when we fetch data from Drupal, the routes we’ve disallowed will not be fetched, ensuring our build time isn’t taken up with stuff we don’t need. You can also do this via Drupal, by disabling routes from the jsonapi-extras admin panel.
Next, we need to review the file--file
endpoint. All of the images for materials and suppliers (the routes we don’t need) are still in that file endpoint, so they will still be processed by Gatsby, and Sharp.
Within Drupal, we’ve created a hook on file uploads, so that if we’re uploading to a page which we want Gatsby to process, the file will be prefixed with static_
. This means that we can use filters on the file endpoint to get back only files prefixed in this way:
Read more about how filters in Drupal work here.
We found that filters were ignored unless we added basicAuth. To do this, enable the HTTP Basic Authentication extension from Drupal. We also had to enable the following setting from Drupal:
$settings[‘trusted_host_patterns’] = array();
However, passing basic auth to Drupal assumes that your files are hosted in the same place. The source plugin passes your auth
headers to the url of the file, which in our case is hosted on s3. Unfortunately s3 will then (quite rightly) reject the request because we’re using incorrect authentication.
If this is also the case with your site, you can use the onCreateNode
hook in gatsby-node.js to link up any files that haven’t been downloaded, and use the createRemoteFileNode
method to download them based on the node’s url. Setting node.localFile___NODE = fileNode.id
will attach the downloaded file back to the node, and you will be able to use the file as normal.
Finally, let’s review the reason we started all of this: build speeds. Without needing to download and process 3000+ images, the total build time dropped from about 8 minutes to 56 seconds.
Hopefully using techniques like this will help optimise your Gatsby build times when connecting to a CMS like Drupal.