Gatsby.JS Live Previews with Drupal

Gatsby.JS Live Previews with Drupal

Professional Article
May 29, 2021

If you have a decoupled Gatsby + Drupal site, then you’re probably annoyed waiting for 5-10 minutes for the build to finish - to see how your CMS changes landed on the actual website. There’s a better way - Gatsby Previews (took me a while to look into it). With Live Previews you can view your new and edited content instantly.

How to enable the Preview

There’s this neat contrib module - called “Gatsby” - https://www.drupal.org/project/gatsby 

It consists of 4 different sub-modules:

  • Gatsby - Improves integration with GatsbyJS including adding Live Preview and Incremental Builds;
  • Gatsby Fast Builds - Enables faster Gatsby development builds by only downloading content that has changed;
  • Gatsby JSON:API Extras - Adds additional enhancers when using Gatsby with JSON:API;
  • Gatsby JSON:API Instant Preview and Incremental Builds - Enables a faster preview experience and incremental builds support when using JSON:API and gatsby-source-drupal.

I usually use all these, except for “Gatsby JSON:API Extras” - this one alters the GraphQL output and it doesn’t always suit me - because I already built my GraphQL queries and I don’t want to alter those.

I’ll consider that you want to enable a special sub-domain: preview, i.e. preview.nikro.me, or, preview.YOURDOMAIN.com.

Once you enable all these - head to: admin/config/services/gatsby/settings

Here you specify the following (example):

  • Gatsby Preview Server URL: http://preview.YOURDOMIAN.com:8000
  • Incremental Build Server Callback Hook(s): http://preview.YOURDOMIAN.com:8000/__refresh 
  • Entity types to send to Gatsby Preview and Build Server: go ahead and check some entities that you want.

Make it as a running Service

I assume you run your builds via some CI/CD process (i.e. CircleCI or Netlify) - so you’ll need to make sure that your Drupal’s server (the one you use for editing content) has also node installed, gatsby, and all the node packages (dependencies) - basically make sure it can run: build or develop.

Edit package.json - add this bit: 

  1. ...
  2.  "scripts": {
  3.     ...
  4.     "preview": "gatsby develop -- --host 'preview.YOURDOMAIN.com --port 8000",
  5.     ...
  6.   },

This will allow us to run ‘gatsby develop’ by running: npm run preview.

If you’re running an Ubuntu machine, that has systemd - create a file here:
/lib/systemd/system/preview_gatsby.service

Here’s a template:

  1. [Unit]
  2. Description=preview_gatsby.js - Preview for YOUR DOMAIN.
  3. Documentation=https://YOURDOMAIN.com
  4. After=network.target
  5.  
  6. [Service]
  7. Environment=NODE_PORT=8000
  8. Environment=ENABLE_GATSBY_REFRESH_ENDPOINT=1
  9. Type=simple
  10. User=ubuntu
  11. ExecStart=/usr/bin/npm --prefix /var/www/PATH/app run preview
  12. Restart=on-failure
  13.  
  14. [Install]
  15. WantedBy=multi-user.target

Here - make sure to change the YOURDOMAIN and the PATH towards your app. The important line here is Environment=ENABLE_GATSBY_REFRESH_ENDPOINT=1 this is what will expose the /__refresh hook and enable our develop - act as a preview service.

Once you’re done with this, run: sudo service preview_gatsby start - if everything goes fine - you should see no errors. You can check for errors (?) by running: systemctl status preview_gatsby.service - green is good, red is bad ?

All good, even though we’re running the gatsby preview and the modules are installed and configured - the missing piece is nginx acting as a proxy. Create a virtual-host, in example: /etc/nginx/sites-availabe/preview.YOURDOMAIN.com with similar contents:

  1.         listen 80;
  2.         server_name preview.YOURDOMAIN.com
  3.  
  4.         root                    /var/www;
  5.         index                   index.html index.htm;
  6.         access_log              /var/log/nginx/proxy.access.log;
  7.         error_log               /var/log/nginx/proxy.error.log;
  8.         include                 mime.types;
  9.         default_type            application/octet-stream;
  10.         sendfile                on;
  11.         keepalive_timeout       300;
  12.         client_max_body_size    256M;
  13.         fastcgi_buffers 16 16k;
  14.         fastcgi_buffer_size 32k;
  15.         fastcgi_read_timeout    120;
  16.  
  17.         location / {
  18.                 proxy_pass              http://localhost:8000;
  19.                 proxy_buffer_size       32k;
  20.                 proxy_buffers           8 16k;
  21.                 proxy_read_timeout      90;
  22.                 proxy_connect_timeout   60s;
  23.                 proxy_send_timeout      90;
  24.                 proxy_set_header        Host $host;
  25.                 proxy_set_header        X-Real-IP $remote_addr;
  26.                 proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  27.                 proxy_set_header        X-Forwarded-Proto $scheme;
  28.     }
  29. }

And then create a symlink in /etc/nginx/sites-enabled and run a test: sudo nginx -t 

Now you’ll have traffic proxied from :80 -> :8000 (preview) and things should work. Now you might be asking - why did we specify to Drupal the :8000 port? Through trial-and-error I came to this conclusion - it’s because Drupal sits on the same machine ? (in my case), so it doesn’t like to go through the nginx proxy, and triggers the hook directly.

Securing the Preview

As you might have noticed - I used http and not https, nor I have specified Gatsby Secret Key - in the configuration of the Gatsby module in Drupal. 

To make things the right way - you’d want your Nginx to listen to 443 instead of 80 -> install let’s encrypt and make sure everything’s secured.

What about that secret? ? Here you can see the example - secret can be used on both sides:

  • In Drupal - you specify the random string.
  • In Gatsby - where you specify the Drupal source (in gatsby-config.js) - you specify the same string.

This adds a layer of protection for previews between the two.

Test and have fun!

I add / edit content once a month or so - and when I do, I start the preview service, get my stuff done and then shut it down (for security purposes, greener planet and all that) - I recommend you do the same ?

Have fun!
 

💡 Inspired by this article?

If you found this article helpful and want to discuss your specific needs, I'd love to help! Whether you need personal guidance or are looking for professional services for your business, I'm here to assist.

Comments:

Feel free to ask any question / or share any suggestion!