Cosmic JS Blog Stay tuned for community news, company announcements and updates from the Cosmic JS team.

How to Build a JAMstack Website


by Tony Spiro on March 21, 2017

Update

This is an older post that shows you how to build a static website using Metalsmith. There are also Cosmic JS resources for static website development using React, Vue, and Gatsby. Go to the Quickstart Guide for instructions on how to install these starters.


There’s been a recent surge of interest in static websites because they offer benefits including fast page loads and security.  And a new term for this new way of building websites, coined by the folks at Netlify, is JAMstack(not to be confused with the most addicting way to play the electric guitar). If you are new to this concept, the JAMstack is comprised of a JavaScript-powered frontend for page interactions (J), APIs to connect to various APIs to get 3rd party functionality (A) and plain old Markup (HTML) which gets deployed to your instance (M).

Smashing Magazine has recently raved about creating their new JAMstack website and is currently undergoing a massive renovation of their existing web properties.  They are drop-kicking their bloated, pain-point-prone WordPress monolith that they currently maintain in favor of a JAMStack-powered website with help from Netlify and the Netlify Open-Source CMS.

Cosmic Jamming

In this article, I will show you how you can use Cosmic JS to deploy your own JAMstack website in just a few clicks.  When you JAM with Cosmic, you not only get the benefit of a fast, optimized static website, but your content is also available in the Cosmic JS API.  This gives other applications easy access to your content which could include landing pages, microsites, or native iOS and Android applications.

TL;DR

1. Install the Cosmic JS Static Website.
2. View the code on GitHub to see how the app is built.
3. Deploy your app to the Cosmic App Server by going to Your Bucket > Deploy Web App.
4. Set up your Webhooks located in Your Bucket > Webhooks.

Getting Started

We’re going to install the Static Website App available in the Cosmic JS App Store.  As you do this, you should also fork the repo to your own repository on GitHub.  This way you can make all the customizations you need to JAM in your own way.

Let’s take a look at how this application is put together.  To follow along, go to the GitHub repo.  Here is the app.js file:

// app.js
var buildSite = require('./build-site')
buildSite()
var express = require('express')
var app = express()
app.set('port', process.env.PORT || 3000)
app.use(express.static('build'))
app.get('/rebuild-site', (req, res) => {
  buildSite()
  res.end('Site rebuilt!')
})
app.post('/rebuild-site', (req, res) => {
  buildSite()
  res.end('Site rebuilt!')
})
app.get('*', (req, res) => {
  res.redirect('/404')
})
app.listen(app.get('port') || 3000, () => {
  console.info('==> 🌎  Go to http://localhost:%s', app.get('port'))
})

First we start with a Node.js application that includes a few routes:

/rebuild-site (both a GET and POST for convenience)
/404
/build (to keep all of our static website build files)

Next let's take a look at how the site is built.

// build-site.js
var Metalsmith = require('metalsmith')
var markdown = require('metalsmith-markdown')
var layouts = require('metalsmith-layouts')
var permalinks = require('metalsmith-permalinks')
var sass = require('metalsmith-sass')
var metalsmithPrism = require('metalsmith-prism');
var Cosmic = require('cosmicjs')
var async = require('async')
var mkdirp = require('mkdirp')
var del = require('del')
var mv = require('mv')
var createPage = require('./create-page')
var config = require('./config')
module.exports = () => {
  async.series([
    // Create build-new folder
    callback => {
      mkdirp(__dirname + '/build-new', err => {
        callback()
      })
    },
    callback => {
      Cosmic.getObjects(config.cosmicjs, (err, res) => {
        var pages = res.objects.type.pages
        var cosmic = res
        // Create dynamic static pages
        async.eachSeries(pages, (page, callbackEach) => {
          var args = {
            page: page,
            pages: pages,
            cosmic: cosmic
          }
          createPage(args, callbackEach)
        }, () => {
          // Create markdown static pages
          var year = (new Date()).getFullYear() // make your footer year dynamic ;) 
          Metalsmith(__dirname)
            .metadata({
              cosmic: cosmic,
              year: year
            })
            .source('./src')
            .destination('./build-new')
            .clean(false)
            .use(sass({
              outputDir: 'css/',
              sourceMap: true,
              sourceMapContents: true
            }))
            .use(markdown( { langPrefix: 'language-' } ))
            .use(metalsmithPrism())
            .use(permalinks())
            .use(layouts({
              engine: 'handlebars',
              partials: 'layouts/partials'
            }))
            .build((err, files) => {
              if (err) { throw err }
              callback()
            })
        })
      })
    },
    // Delete build folder
    callback => {
      del([__dirname + '/build']).then(() => {
        callback()
      })
    },
    // Move build-new to build folder
    callback => {
      mv(__dirname + '/build-new', __dirname + '/build', { mkdirp: true }, () => {
        callback()
      })
    },
    // Delete build-new folder
    callback => {
      del([__dirname + '/build-new']).then(() => {
        // done
      })
    }
  ])
}

 This file holds all the magic, let's unpack what's happening here:
1. We're using Metalsmith to build our website files.  There's other build tools for this, but this is the best one (IMO) for JavaScript-built static sites.
2. The build-new folder is created as a temporary place for our new build.  This is so we don't get any down-time from users currently on the website.
3. Next we will get all Objects in our Cosmic JS Bucket using the Cosmic JS NPM Module and method Cosmic.getObjects
4. Then we will parse from our response all Pages.  Then begin a loop to create a new static page for each Page Object.
5. Each Page Object will then be passed to Metalsmith to build our Page.
6. After Metalsmith is done Jamming out our Markup to the build-new folder, the build folder is deleted.
7. Without blinking an eye the new build folder is created with the fresh build.

And that's it!  Your Cosmic JS content is now available in static form in JAMstack generated HTML files.  PLUS you have access to all of your content via the Cosmic JS API.  Also if you need someone who's not versed in Markdown to edit content, they can easily edit content via the WYSIWYG editors in the Cosmic JS Dashboard.

Using Webhooks for Automatic Rebuilds

Cosmic JS offers a great way to automatically rebuild your JAMstack static website on every content edit with Webhooks.  Setting up webhooks is easy.  Just go to Your Bucket > Dashboard > Webhooks and set the POST to the endpoint and action of your choice. In this example, you can set your Webhook to POST to [your-app-hostname]/rebuild-site.

In Conclusion

In this article we talked about a recent rebrand of static websites (Jamming sounds a lot more fun than static website building).  We talked about how you can install a JAMstack-enabled website in a few clicks using the Cosmic JS Static Website App. And we showed you how to automatically rebuild your website whenever content is changed via Cosmic JS Webhooks.  If you have any questions, join our Slack channel and reach out on Twitter.

You may also like


We're always trying to make the process of editing content easier.  We just released an update that makes editing your content in your Cosmic JS Buckets easier on the eyes.  One of the goals of the update was to make the Object edit view design look less busy. 

In this latest installment of the Cosmic JS Developer Spotlight Series, we sat down with Aaron Vail, a Google Analytics Implementation Analyst and Software Developer at Main Event Entertainment's corporate headquarters in Plano, Texas. Check him out on Twitter and LinkedIn, and enjoy the Q/A.

In this Spotlight we are focusing on Jon Bloomer, who recently launched the Cosmic JS-powered website for his business Tone Temple.  Jon took some time to answer a few questions about his business, his development process and some of his favorite non-dev rockstars.

This is blog number one on the new Cosmic JS blog page.  Hopefully this will help me find the best way to help developers and publishers use this platform easier and more efficiently.

Brand Managers manage, well, brands.  Seems simple enough right?  It does in title and theory alone.  Managing a brand means managing the brand’s tone, voice, messaging, consumer segmentation, price points, marketing, advertising and all of the subsequent elements and assets that fall out of such an engagement.  Having managed brands for years myself, I can attest to the magnitude of the job at hand.  Once the client has agreed upon a general direction, it becomes the brand manager’s responsibility to ignite passion and results from the internal agency team that services the account.  As my workload would increase month over month as business heated up or an account was grown, I went through the whole Automation | Delegation | Elimination routine to see what I could cut out of my schedule as busy work.  The problem?  I was only one person.  I could only affect hours tallies on my end, but had little to no influence over design, development, copywriting & production. 


The area that always seemed to be the weak link in terms of staying on budget was in development.  Boutique agencies struggle to attract qualified talent with their long work hours and subpar compensation, and then after taking a gamble on a more junior talent that is developed over time, retention is a beating.  Companies line up with development jobs that pay 2X, sometimes 3X what a boutique agency is willing to part with for that developer’s compensation package.  This is all before taking into account staging servers, hosting servers, CMS logins, local installations of CMS systems and all of the red tape and bureaucracy associated that can bog down a productive workflow.  As a result, my quotes back to clients for websites, microsite, landing pages and applications were always a bit higher than they were expecting.  I started searching for a cloud-based solution to my CMS woes to cut out some of the middle men and see if there was an easier way to 'get this digital property live'. 

I found 
Cosmic JS.  Had I been told as a Brand Manager that I could eliminate the local CMS, the hosting server and the shared logins of content editing, I would have seen the value immediately.  No longer having to build APIs on a per-CMS / per-client basis, no longer having to build out a proprietary backend, yet still attaining the same custom-value would have been a lifesaver and a half for a brand manager focused on the bottom line.  It would have easily cut my back end developers’ hours estimates by 40%, eliminated costly hosting servers and would have streamlined content-centric employees within the agency to not have to deal with the red tape of updating content within a traditional CMS. 

Whether we picked out a
content-ready application or plugged GitHub into Cosmic JS, I’m seeing time and cost savings at every turn.  Music to a brand manager’s ears, and music to a boutique agency’s margin and bottom line.  As it turns out, it also benefits the client as their content is put first, their content is pushed live more quickly and is devourable globally on any device.

After many weeks of development we are excited to announce a couple of big updates.  We have completely rebuilt both our REST API docs and NPM module.