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

How to Build a JAMstack Website


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


It's now even easier to add metafields to your objects.  Available metafields include: plain text, plain textarea, html textarea, select dropdown, object select (for object connections), image / file and date.

Sign in and check out the available metafield options that make it so easy to add dynamic content to your websites and apps.


In this installment of the Cosmic JS Developer Spotlight Series, we sat down with Ben Hong, a Senior Front End Engineer residing in Washington, D.C. Ben wears several hats, first as a Front End Engineer at GitLab, as well as being an active Google Developer Expert and Vue.js community partner. He's also put some work into VuePress, one of the newest static site generator for Vue.js projects.

In this installment of the Cosmic JS Developer Spotlight Series, we sat down with Jacob Knaack, a Web Developer and Technical Communicator residing in Seattle, Washington. Jacob is a Front End Developer at restack, a development studio that finely crafts websites and apps. Jacob is also a frequent contributor to the Cosmic Community, having recently built both the Progressive Apollo Blog as well as the Gatsby Documentation Website. Follow Jacob on LinkedIn and GitHub and enjoy the conversation.

In this article, Iā€™m going to show you how to create an easy-to-manage website navigation menu using the powerful Cosmic JS Metafields.  Because navigation needs to be both flexible and nestable Cosmic JS Metafields allows you to create nestable data structures with parent / child relationships easily with a simple drag and drop in the CMS.  Cosmic JS has made this once time-consuming task easy to implement in any website codebase and intuitive to manage in the Cosmic JS CMS API.

Extensions are a powerful component of the Cosmic JS that allow you to create custom views in your Bucket Dashboard. We've recently made some updates to make using this feature even better.

We have a mission to help every digital team be more efficient by providing a simple API to power content for their website or application.  And this milestone provides some validation for that goal.  We are grateful to all our users who are joining us on this journey.