Skip to content
Website for Kelly Malone @ WordsUp.
JavaScript CSS HTML Shell
Branch: dev
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


A modern headless CMS SDK for



This README file outlines how to get up and running with a Clutch Stack. Its presented in proper order of operations. The documentation assumes some key things about you as a developer:

  • You know well and work with AWS
  • You know well and work with Prismic
  • You know well and work with CircleCI
  • You know well and work with Node.js
  • You know well and work with one of the template languages here

Table of Contents


Code Setup Round 1

This walks through creating your new Clutch project.

  • Install the clutch-cli by running npm i -g clutch-cli;
  • Wherever you keep projects on your computer, make a new directory for
  • Then cd into that directory and run clutch init

AWS Setup

Create the Clutch Stack within AWS OpsWorks using the clutch-chef recipe documentation. Make sure you hold onto that clutch.pem file you get from setting up a Key Pair as you'll use it later to store the Fingerprint in Circle CI for SSH Permissions. You'll also want to keep it in .clutch for use with deploying tokens to your instances.

S3 Setup

This is optional, however you can create an S3 bucket on AWS and add the bucket URL to the clutch.config.js as your aws.cdn value. Likewise, change the aws.cdnOn value to true. Next you'll need to create an AWS IAM user and group and save the access key and secret key so you can add them to Circle CI later.

CloudFront Setup

This is even more optional, but if you need a real CDN you can spin up a CloudFront Distribution and attach it to your S3 bucket. If you do this you'll want to update the aws.cdn value in the clutch.config.js file with your CloudFront URL.

Route 53 Setup

If you plan on launching your website you'll likely need to setup the DNS in Route 53. You'll add a hosted zone for your domain. Then you'll create record sets. So a full Clutch Stack for would at least need you to create these records for the hosted zone:

  • An A Record for
  • An A Record for
  • An A Record for

Headless CMS Setup ( Prismic )

These steps cover the basics of bootstrapping Prismic for Clutch.

  • Create your Prismic repository in your dashboard
  • In your repository Settings under Previews add the following sites:
    • Site name: sandbox, Preview URL: http://localhost:8001/preview/
    • Site name: staging, Preview URL:
    • Site name: production, Preview URL:
  • In your repository Settings under API & Security do the following:
    • Enable the API Endpoint CDN if it isn't already on
    • Choose Open API for your Repository security level
    • If you need to use a Private API, choose that
      • Under the Generate an Access Token section enter a name and click Add this application
      • This makes an app config with oAuth and token access
      • Under the application settings you just made copy the Permanent access tokens - Access to master
      • Create a file at .clutch/prismic.access.token and paste the token in that file
      • Next in clutch.config.js change api.token to true
      • Run the .clutch deploy scripts so your instances have access to these tokens
        • npm run deploy:clutch:staging
        • npm run deploy:clutch:production
  • In your repository Settings under Webhooks:
    • Enter the URL for your site:
    • Enter a Secret, I use randomkeygen
    • Create the file .clutch/prismic.webhook.secret and put the key in this file
    • Click "Add this webhook"
    • Clutch will now listen for webhooks, see server/core/router.js
  • In your repository Custom Types create a Single type called Site
    • In the configuration for this type paste the contents of models/Site.prismic.json in the JSON editor
  • In your repository Custom Types create a Repeatable type called Page
    • In the configuration for this type paste the contents of models/Page.prismic.json in the JSON editor
  • In your repository Content workspace create a new instance of the Site model
    • Enter your details, these are high level site-wide settings that will be exposed in your templates
  • In your repository Content workspace create a new instance of the Page model
    • Call it Home with the slug home and a description
  • Jump back over to your Site instance, click the Navigation tab and add a navigation item for the Home page linking it to the actual page document
  • You can follow the steps for making the Home page and create the Example page

Code Setup Round 2

This walks through adding the final details to your Clutch project and pushing it to Github.

  • In the root package.json file enter your AWS EIPs for config.aws_ec2_staging_host and config.aws_ec2_production_host
  • Create your new repository on Github
  • From the root of your new Clutch project source code initialize the repository git init
  • Add the clutch source files git add .
  • Make your first commit git commit -m "clutch bootstrap"
  • Add the remote origin git remote add origin
  • Push the source code up to Github git push -u origin master
  • Create the dev branch git checkout -b dev
  • Push the dev branch git push origin dev
  • On the Github website for you new repository settings click the branches tab and set dev as the new default branch

Circle CI Setup

Now that AWS and Prismic are setup and the code is on Github you can connect your project repository to Circle CI. Under the repository settings in Circle CI you'll need to add the SSH key from your clutch.pem file you created while setting up the AWS OpsWorks Clutch Stack under SSH Permissions. Then you'll need to add the following environment variables:

  • AWS_USER: ec2-user
  • AWS_DEST: /var/www/html/

If you decided to use an S3 bucket then you'll also need add the bucket information and IAM credentials in the Circle CI environment variables:

  • S3_BUCKET:
  • S3_REGION: aws.s3.bucket.region
  • S3_ACCESS_KEY: aws.iam.access.key
  • S3_SECRET_KEY: aws.iam.secret.key

From the Circle CI website you can now run your first build for your dev branch which will deploy to your AWS staging instance.


This section breaks down aspects of the Clutch SDK ecosystem which is rooted in node.


The Clutch SDK assumes 3 specific environments for your workflow.

  • sandbox ( local development )
  • staging ( aws dev instance )
  • production ( aws live prod instance )

Some behaviors to note when working with Clutch and environments:

  • If you're using an S3 bucket it will only be utilized on production
  • Likewise if you're using a CDN it also will only be used on production
  • AppCache is enabled for production only by default ( I recommend leaving this as is )
  • All that in mind it should be no surprise that Webpack only gzips for production


The Clutch node server uses a convention over configuration approach in regards to accessible endpoints. The URI format is :content-type/:uid. When working with Prismic you can define Collections around documents. When you do this Clutch will first attempt to see if :content-type is a Collection first before resolving to the root idea of a content-type. A good example case is to have a content-type called Casestudy. You may not want your URLs to be /casestudy/some-title. Maybe you want it to be /work/some-title. If you create a Collection called work and add the Casestudy content-type as a filter you can then use the /work/some-title URL format.


The Clutch node server also operates as a JSON API for your data. The format is /api/:content-type/:uid. You can use the API for partial renderings if you pass ?format=html&template=name.of.template along with your request. Partials are loaded out of the /template/partials directory.


The Clutch node server implements a pub/sub model for interacting with requests. You can subscribe to content-type requests and modify the query and context in any way you need. The client, api, and query objects passed to your query handlers will be representative of the CMS you are using. The context passed to your context handlers is the ContextObject instance.

The default server/app.js has a couple basic examples. You have to return either the query or a new Promise for your query handlers. When returning with a Promise you must resolve with an object that as a results Array or reject with an error message. For your context handlers you have to return the context.


The Clutch node server uses the same convention for templates as it does for endpoints. It looks up endpoints in the /template/pages location. So reusing our Casestudy example from the server docs we could make a casestudy.html file in the pages directory and that would render for Casestudy endpoints. We could also make the work.html file to utilize the Collection filter functionality of Prismic. The core template anatomy is as follows:

  • template/index.html: This is your layout
  • template/pages: This is where endpoints lookup templates
  • template/partials: This is where API partial endpoints lookup templates when using /api/:content-type/:uid?format=html&template=name.of.template
  • template/site: These are core structural elements for the document like nav or header or footer
  • template/**?: Of course you can make any folder structure you like. I often make a directory called slices when using Prismic's dynamic slicezone functionality.

When working with templates you are looking at a normalized Template Context Object. You have normalized site and navi data structures created from your headless CMS Site content type. Depending on your content context you will either have an item object reference or an items array reference.

The Template Context Object tree:

    site: {object},
    navi: [array],
    page: "string",
    cache: boolean?,
    error: "string",
    timestamp: number,
    item: {object},
    items: [array],
    stylesheet: "string",
    javascript: "string",
    config: {object},
    dom: {[prismic-dom](}

The Navi Context Object tree:

    id: "string",
    uid: "string",
    type: "string",
    slug: "string",
    title: "string",
    style: "string"


These are some general UI tools I find myself using on projects for various tasks.

You can’t perform that action at this time.