Tony Spiro
March 21, 2017
Update
Check out the Jamstack CMS knowledge base page to learn how you can use Cosmic to build a Jamstack site using Gatsby, Nuxt.js, Gridsome, and more.
Continue reading for an example using Metalsmith.
Introduction to Jamstack
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 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 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 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 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 Bucket using the Cosmic 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 content is now available in static form in JAMstack generated HTML files. PLUS you have access to all of your content via the Cosmic 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 Dashboard.
Using Webhooks for Automatic Rebuilds
Cosmic 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 Static Website App. And we showed you how to automatically rebuild your website whenever content is changed via Cosmic Webhooks. If you have any questions, join our Slack channel and reach out on Twitter.