{ Rebuilding serundeputy.io w/ Backdrop CMS API and Nuxt as Frontend }

As many developers do I use my personal website as a place for technical explorations to try out different ideas. Over the years this site has been on FreeBSD + WordPress, Debian + Drupal 7, Debian + Drupal 8 beta.13, and Debian + Backdrop CMS. As of late I've been interested in API first stacks with javascript frontends. Most of the players in the realm of CMSs these days offer an API or a way to serve up the content they store in a Headless or Decoupled manner.

I was interested in bringing these API first ideas into the world of Backdrop, so I gave it a go, and had quite a bit of fun along the way 😊. The result of this exploration is this website (serundeputy.io) and the Headless module for Backdrop.

Tech Stack

One of the most complicated parts for me on just about any project is how to get started. Choosing the tools, setting a project road map, and then implementation. In the world of headless there are a lot of choices to be made, so of course I had to make some. I knew I wanted Backdrop for the data store, API and content authoring experience. For the frontend javascript, but which one?

There are a lot of javascript frameworks out there these days, but recently myself and my colleagues have been drawn to Vue.js which is a popular and powerful javascript framework. That led us to the discovery of Nuxt JS and so the tech stack is rounding out. Ultimately here are the choices I made:

  • Lando ~ as always I'm using Lando to manage the infrastructure and dev dependencies of the two apps
  • Backdrop CMS ~ Backdrop is the datastore and API to feed the Nuxt frontend app
  • Nuxt ~ The frontend app that is making API calls to Backdrop to feed the data into the presentation layer

Now with the tools researched and chosen it is time to start building which is by far my favourite part.

Infrastructure

As I've mentioned Lando is the corner stone of the local development architecture.  There are many dependencies in this set up that span two apps, PHP, Javascript, and of course servers. What I have is two apps, just as they exist in production, two separate apps that communicate with each other. Each has its job and focuses on it and is able to do it well.  Backdrop offers a good authoring experience, stores the data, and an API to deliver the data to the frontend. Nuxt focuses on the presentation layer, offers a speedy and dynamic user experience.

The Backdrop app:


# Backdrop recipe
name: serundeputy

# Start with the default Backdrop recipe
recipe: backdrop

# Configure the Backdrop recipe
config:
  via: nginx
  php: '7.0'
  webroot: www
  backdrush: dev
  database: mariadb:10.2
  xdebug: true

services:
  appserver:
    run:
      - cd $LANDO_MOUNT && composer install
      - composer global require laravel/envoy

# See: https://docs.lndo.io/config/tooling.html
tooling:
  envoy:
    service: appserver

Nothing too special here just a Backdrop recipe with some deployment tooling. The magic on the Backdrop side comes with the Headless module to turn the CMS into an API. The Nuxt app:


name: serundeputy-fe
proxy:
  appserver:
    - serundeputy-fe.lndo.site
env_file:
  - .env
services:
  appserver:
    type: node:10
    command: cp -n /app/.env.example /app/.env && yarn dev --hostname 0.0.0.0 --port 80
    install_dependencies_as_me:
      - yarn install
tooling:
  yarn:
    service: appserver
  npm:
    service: appserver
  node:
    service: appserver
  nuxt:
    cmd: /app/node_modules/.bin/nuxt
    service: appserver

This is a custom .lando.yml file that serves up the Nuxt app. The fancy occurs on the appserver command command: cp -n /app/.env.example /app/.env && yarn dev --hostname 0.0.0.0 --port 80 which allows us to serve the node app inside the Lando/Docker container. In this way I don't have to worry about local php, yarn, npm versions; Lando handles all that for me with just a few configuration directives in the respective .lando.yml files.

Headless Module

The Headless module is the magic that turns Backdrop into an API. I originally wrote the module back in 2016 ⌛, and through the course of this project it received a lot of love and updates 💌. It now supports serving nodes, terms, views, and paragraphs as JSON endpoints! Install it like you would any Backdrop module and enable it. You will then have an admin page to manage which pieces of content you wish to expose as JSON: /admin/config/services/headless:

Headless config page

Now just check the boxes for the content you would like to expose as JSON and whala instant API.

Nuxt

Now to use a Nuxt app to consume the JSON and make the site. Nuxt is great and offers fast, easy to manage, componenttized architecture. To get started with Nuxt you can hop over to their documentation page or see this video I made for Nuxt on top of Drupal 8, but as far as what serves the data to Nuxt it does not care if it is Drupal, Backdrop, WordPress or anything else! here is the video:

I've started the video at about 3min in where the Nuxt config starts, but feel free to watch from the beginning if you want to see the Drupal 8/ContentaCMS set up as well.

Deploying

I'm hosting on Linode. I've set up two different apps on the same server one is the Backdrop API site and the other the Nuxt app. There are corresoning nginx sites-enabled files for each. For Backdrop the root points to where Backdrop lives on the server:


root /var/www/serundeputy/www/;

and likewise for Nuxt:


root /var/www/serundeputy-frontend/.nuxt/;

which is where the built app lives.

You deploy any Backdrop code changes as you normally would. In my case I'm using envoy to deploy. For the Nuxt app we need to deploy the code and then build the app:


git fetch
git merge origin/master
yarn
yarn run build
# find nuxt start pid && kill 
# find node/nuxt pid && kill 
# start nuxt server and run in background.
nohup yarn start &

I think in the future i'll add those steps to envoy as well as there own task, but for now I'm doing it manually.

Conclusion

It was great fun to turn Backdrop into an API and write the Headless module! You can give it a whirl too. I also very much enjoyed Nuxt and Javascript.

Follow me on twitter @serundeputy