Information for: DEVELOPERS   PARTNERS

Setting up a local Drupal and Node.js application

Node.js with Decoupled Drupal on Cloud Platform – Back to intro
Previous lesson - Understanding the architectural workflow
Next lesson – Deploying your applications to Cloud Platform

Lesson Goal

Structure a local Drupal website and a local JavaScript application for a decoupled architecture.

In this lesson, we will stand up a pre-built Drupal website locally using some common Acquia build tools Acquia BLT (Build and Launch Tool) & Drupal VM. The Drupal sample content and fields demonstrate a clear correlation between Drupal and the JavaScript application, allowing for easy extensibility.

In order to complete this lesson you will need to have the following software packages installed:

You’ll also need PHP CLI version 7.2 or greater installed in order to complete the installation. On MacOS the easiest way to install PHP is with Homebrew.

For a complete list of prerequisites and more extensive setup instructions, refer to the BLT onboarding and DrupalVM quick-start documentation.

Download and Install Code Dependencies

Download the Drupal codebase by cloning the repository with:

git clone

Once the code has finished downloading, cd into the folder with:

cd decoupled-drupal/

From this location, install the package dependencies with:

composer install

Stand up the local Drupal instance

For the next steps, set up the local Drupal site with BLT & Drupal VM to expedite the process. These steps can also be accomplished with a standard local LAMP stack or a similar preference, with the assumption of maintaining the same localhost name (

From the same decoupled-drupal/ folder location, install the BLT alias:

composer run-script blt-alias

Setup your local virtual box with Drupal VM, using the BLT command:

blt vm

This will indicate a question Do you want to boot Drupal VM?, which you can type “y” to proceed. You might want to get a cup of coffee while this completes.

Build and install the Drupal installation with:

blt setup

CD into docroot/ and log into your Drupal application with:

drush @decoupled.local uli

If you are seeing errors with the uli command or do not see the alias with the drush sa command, you can also shell into the vagrant box. To proceed with this workaround, follow these instructions:

> vagrant ssh
> cd docroot/
> drush uli

You can now review the test content at

Content page showing test content including option to add content

Setting up the Node.js Application locally

The next steps involve setting up a previously constructed JavaScript application to work in tandem with our local Drupal application. Follow this step only after your local Drupal codebase and site is set up. For our example JavaScript application, Node.js is leveraged to create the pages, while using the Ember.js framework to pull the API data.

Install the following software packages (if not previously installed):

For a complete list of prerequisites and setup instructions, refer to the decoupled-js README.

Download and install the Application

Download the JavaScript codebase by cloning the repository with:

git clone

Once downloaded, cd into your application root with:

cd decoupled-js/

We will now install the required node modules with:

npm install

Now that the installation is complete, serve and view the JavaScript application locally at http://localhost:8080 with:

npm start

You can now view your Node.js application which is displaying the content from Drupal!

Node.js application displaying the "Decoupled Drupal" architecture

Overview of Current Architecture

The two local applications are intended to display the scenario of a “Decoupled Drupal” architecture. The Drupal CMS website serves as a data source to collect data. The Drupal content types and fields are used to structure the data.

Once the data has been structured and created, it is then exposed through an API endpoint in Drupal. The purpose of the API endpoints is to allow data to be used within our JavaScript application. In common scenarios, you could allow data to be sent back and stored into Drupal. For this tutorial, we are only pulling data from Drupal.

API endpoint diagram showing how data is sent back and stored into Drupal

About the Drupal Application

The Drupal application is built using the “Headless Lightning” distribution as its functional baseline. Headless Lightning is a more opinionated sub-profile of the popular Lightning Drupal distribution intended to be used as a back end for decoupled applications. It includes two primary features: the Lightning Content API, and a Headless UI. The Lightning Content API (which is also included in the standard Lightning distribution) exposes Drupal entities via a JSON-based REST API. The Headless UI simplifies the Drupal administrative back end and content authoring experience to be more accessible to users who might be less familiar with Drupal’s administrative patterns.

The Drupal application provides two content types (“Cats” and “Dogs”) and populates them with sample data. Each of the content types have a handful of fields for data collection.

Drupal 8 Cat A content type page showing sample populated data

The various content nodes are then exposed as API endpoints using the JSON API module. These nodes can be viewed as a collection for that content type or by individual ID based on selection. While most content scenarios are addressed with the node patterns like /jsonapi/node/{content\_type}, others warrant combining user information as /jsonapi/node/{content\_type}/{uuid}.

JSON API module

About the Node.js Application

The Node.js application is a collection of modules which uses specific functionality separately for a web server and the application itself:

  • The ‘/server’ folder is designated to create a web server in which the application will layer upon. The ‘server.js’ file uses the express.js web application framework to serve the application on port 8080 on your local machine.
  • The ‘/client’ folder is designated for the application’s functionality that will interact with the content served from the Drupal API.

Since the core functionality of the application revolves around ingesting an external API, the application uses the Ember Data library. Ember Data does a great job of handling the persistence of the data model, regardless of record origin. The application validates and maps records according to the Drupal entities by routes according to the JSON API standards for the pertinent URL (jsonapi/node/{nodetype}). The records are then parsed appropriately with the associated routes by querying the ID.

Ember Data library