ButterCMS: A Headless CMS

By Brandon Nicoll, Software Engineer, ButterCMS

This tutorial explores creating and managing content for an example online store using ButterCMS, a fully managed headless content management system (CMS). You learn how to deploy your store app by using App Engine and examine some options for scaling and monitoring the app.

Web developers are often asked to build websites where other teams manage the content that is published. On the Earth Class Mail website, for example, web developers create and maintain the homepage, but the marketing team administers most of the content.

Traditionally, you might manage such content by using CMS templates. With respect to site development, design, and maintenance, your challenge is how to integrate the CMS-managed sections into the rest of the website. Now you have two systems to maintain: the CMS and the web framework you used to develop the main website. Moreover, in such systems, you typically maintain a separate CMS admin site and database for the content editors to log in and manage content.

A headless CMS solves these issues, by allowing you to feed CMS content into your existing website, in your existing framework, and leveraging existing style assets. The primary difference from a traditional CMS is how the headless CMS retrieves and consumes content and data. With a traditional CMS, you rely on templates and plugins to assemble web pages. With a headless CMS, you retrieve relevant content by using simple API calls, and integrate that content with a web framework to build rich, and fully customizable web pages. This difference decouples the content from the website, allowing content editors to make updates without needing to change templates and redeploy the site.


ButterCMS, or simply "Butter," is a Software as a Service (SaaS) offering for headless CMS. Butter minimizes or eliminates the setup, configuration, and hosting of the CMS backend. Butter offers client libraries for most of the popular programming languages and frameworks used for web development. Using these client libraries, you can integrate managed content into your app. And if Butter doesn't support your preferred language or framework, it offers a REST API. In addition, Butter also provides a UI for content editors.

App Engine

In this tutorial, you use App Engine to deploy your store app. App Engine is a fully-managed developer experience to deploy apps built by using Node.js and many other web frameworks. App Engine automatically scales the service in response to load and takes care of such operational concerns as provisioning, health checking, load balancing, and healing. App Engine lets you focus on writing code to create business value rather than on managing infrastructure.


  • Use Node.js and ButterCMS to develop a simple backend service, or content service, that powers the website for an example store.
  • Develop a simple frontend for the website using Node.js and the content service.
  • Use App Engine to deploy the content service and the website.
  • Use App Engineto set up scaling for the website.
  • Use Stackdriver Monitoring to check the health of your content service and website.


This tutorial uses App Engine, which is a billable service. You can use the pricing calculator to estimate the costs for your projected usage. New Google Cloud Platform (GCP users might be eligible for a free trial.

Before you begin

  1. GCP プロジェクトを選択または作成します。

    [リソースの管理] ページに移動

  2. プロジェクトに対して課金が有効になっていることを確認します。


  3. Install and initialize the latest version of the Cloud SDK:

    Download the Cloud SDK
  4. Create a ButterCMS account.
  5. Prepare your environment for Node.js development.

    Go to the Setup Guide

Architecture overview

You use Butter to define and manage the content for the store website, and you use the Butter API to retrieve that content. A content service encapsulates the implementation details for communicating with the CMS to retrieve the content. The content service converts the content into a format that the website's presentation logic can consume. This logic communicates only with the content service and not with Butter. This decoupling allows you to keep the system extensible and maintainable. For example, you could combine content from different sources or swap Butter with another headless CMS simply by changing the content service and keeping the rest of the system unchanged.

Butter architecture

Managing content in Butter

To manage the dynamic content for the store website, you use a feature of Butter called collections. Collections are lists of user-defined objects, where each object encapsulates information about an individual entity. In this example, an object represents a product listed on the store website. Butter handles storing all the information and provides a UI where you can manage that information.

Create a workspace

Before you can create a collection, you first need to create a workspace. A workspace provides a framework for organizing the content and might represent individual pages or groups of related content.

On the navigation menu in the Butter admin page, click New Workspace.

New Workspace

Create a collection

Now that you have a workspace, you can create a collection.

  1. In the workspace you just created, click New Content Field, and then click Collection.


  2. In the Content Label field, enter a name for the collection and click Create.

    Content Label

  3. Define the properties for each product.

    product properties

  4. Click Add to [COLLECTION], where [COLLECTION] is the name you specified in step 2.

    Add to collection

  5. Fill in the form fields and click Save. Your newly added product is displayed on the collection overview page.

    Collection overview

Edit content

After you've defined a collection and populated it with your initial data, the site's content editors can follow the same steps to change existing objects, add new objects, or remove objects that are no longer needed.

content editing

Creating a content service

This section assumes that you have installed Node.js and npm on your workstation. Unless instructed otherwise, you enter the following commands in a command shell on your workstation.

  1. Create a directory for your content service project:

    mkdir contentService

    cd contentService

  2. To initialize the project for Node.js, enter npm init.

  3. Follow the prompts to enter any relevant information.

  4. Install the npm packages buttercms and express. express is a web application framework, and buttercms is a client library for Butter's API.

    npm install express --save

    npm install buttercms --save

Implement the service

To implement the content service, you need your Butter API key.

  1. To find your key, go to Settings.

  2. In your text editor of choice, create a file server.js that will contain the code for the content service.

  3. In server.js enter the following, replacing [YOUR KEY] with your Butter API key.

    const express = require('express');
    const app = express();
    const butter = require('buttercms')(‘[YOUR KEY]');
    app.get('/hotproducts', function (req, res) {
      butter.content.retrieve(['hotproducts']).then(function(resp) {
        var hotProducts = resp.data.data;
    const PORT = process.env.PORT || 8080;
    app.listen(PORT, () => {
      console.log(`App listening on port ${PORT}`);
      console.log('Press Ctrl+C to quit.');
  4. Start the server.

    node server.js
  5. Go to http://localhost:8080/hotproducts. You see the following JSON representation of the products you added earlier.

             "description":"A t-shirt with Brandon on it",
             "productname":"Brandon T-Shirt",
             "description":"A mug with Brandon on it",
             "productname":"Brandon Coffee Mug",

    You are now ready to deploy the service to App Engine.

Deploy the service

This section assumes that you have Cloud SDK installed and initialized and that the project directory you created earlier (contentService) is the current working directory.

  1. Create a file named app.yaml that contains the following:

    runtime: nodejs
    env: flex
  2. Deploy the app.

    gcloud app deploy

    As the code is built and deployed, progress updates are displayed in the terminal window. The output might look familiar if you have used Docker to build container images before. When the deployment is done, the content service is live and publicly accessible.

Implementing a frontend website

At this point, the content service is ready to be consumed by a frontend. In this section, you create a frontend, a crude implementation of a website, to pull in the content data from the content service and return HTML.

Create the website

  1. Create a directory for the frontend:

    mkdir eCommerceSite

    cd eCommerceSite

  2. Initialize the project for Node.js.

    npm init
  3. Follow the prompts to enter any relevant information.

  4. Install the express npm package.

    npm install express --save
  5. Install the npm package request, which you use to make the REST call to contentService.

    npm install request --save
  6. When you deployed contentService to App Engine, you were given a public URL. Make note of that URL, open your text editor, and create a server.jsfile that contains the code to return the homepage HTML.

    const express = require('express');
    const app = express();
    const https = require('https');
    const options = {
      hostname: 'contentservice-173519.appspot.com',
      port: 443,
      path: '/hotproducts',
      method: 'GET'
    app.get('/', function (req, res) {
      var html = '';
      const contentReq = https.request(options, (contentRes) => {
        contentRes.on('data', (d) => {
          var data = JSON.parse(d);
          for (i = 0; i < data.hotproducts.length; i++) {
          html += '<li>' + data.hotproducts[i].productname + '</li>';
        res.set('Content-Type', 'text/html');
    const PORT = process.env.PORT || 8080;
    app.listen(PORT, () => {
      console.log(`App listening on port ${PORT}`);
      console.log('Press Ctrl+C to quit.');

Deploy the website

Follow the same instructions as in the previous section to create an app.yaml file, and then run gcloud app deploy to deploy the website to App Engine.


App Engine provides several scaling options that you can use to configure how the content service and the example website scales in response to load. You specify these options in app.yaml.

Manual scaling

With manual scaling, you set the exact number of App Engine instances you want the app to run in. If you later change the number of instances, you must update app.yaml manually.

Here's an example app.yaml entry.

  instances: 2

Basic scaling

With basic scaling, you set the maximum number of instances and the amount of time an instance can go without serving a request before being shut down. This option enables App Engine to shut down unneeded instances.

Here's an example app.yaml entry.

  max_instances: 3
  idle_timeout: 3m

Automatic scaling

Automatic scaling offers a wider range of parameters that define how App Engine manages scaling for the app, for example, setting minimum and maximum instances.

Here's an example app.yaml entry:

  min_num_instances: 5
  max_num_instances: 10
  min_pending_latency: 45ms
  max_pending_latency: automatic
  max_concurrent_requests: 100

You can find more details about these scaling options for Node.js applications.


With your content service and website up and running, you can monitor their health by using Stackdriver Monitoring. This section describes how to create example email alerts for 95-percentile response time latency exceeding a threshold.

Activate Stackdriver Monitoring

  1. In the GCP Console, ensure that the project you have been using for this tutorial is the currently active project.
  2. In the Products and services menu, under Stackdriver, click Monitoring.

    After you sign in, you are prompted to link the currently active project to an existing Stackdriver Workspace, which you just created. As soon as you link your project to your Stackdriver Workspace, you are ready to add alerts.

Add an alert

  1. On the left-side navigation menu, click Alerting, and then click Create a Policy.

    Create a Policy

  2. In the Create new alerting policy page, under Conditions, click Add Condition, and then click Metric Threshold.

    Metric Threshold

  3. Define the desired threshold condition for the alert as shown in the following image.

    threshold condition

  4. Click Save Condition.

  5. In the Create new alerting policy page, in the Notifications field, enter the email address to receive email notifications when the alert condition is met.

  6. To start the monitoring, click Save Policy. For information about any charges you might incur, see Stackdriver Pricing.

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

  1. GCP Console で [プロジェクト] ページに移動します。

    プロジェクト ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[プロジェクトの削除] をクリックします。 プロジェクト名の横にあるチェックボックスを選択し、[プロジェクトの削除] をクリックする
  3. ダイアログにプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

What's next

  • Try out other Google Cloud Platform features for yourself. Have a look at our tutorials.