Gatsby.JS Live Previews with Drupal
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:
... "scripts": { ... "preview": "gatsby develop -- --host 'preview.YOURDOMAIN.com --port 8000", ... }, …
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:
[Unit] Description=preview_gatsby.js - Preview for YOUR DOMAIN. Documentation=https://YOURDOMAIN.com After=network.target [Service] Environment=NODE_PORT=8000 Environment=ENABLE_GATSBY_REFRESH_ENDPOINT=1 Type=simple User=ubuntu ExecStart=/usr/bin/npm --prefix /var/www/PATH/app run preview Restart=on-failure [Install] 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:
server { listen 80; server_name preview.YOURDOMAIN.com root /var/www; default_type application/octet-stream; sendfile on; keepalive_timeout 300; client_max_body_size 256M; fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; fastcgi_read_timeout 120; location / { proxy_buffer_size 32k; proxy_buffers 8 16k; } }
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!
Comments:
Feel free to ask any question / or share any suggestion!