NodeJS Logo

Node.js blog engine

ButterCMS is an API-based Node.js blog engine that integrates with Node.js. Use ButterCMS for your Node.js apps to add CMS-powered blogs, dynamic pages, and more. Butter plays well with all view-layers including React, Angular, Jade, and Vue.

Table of Contents

Introduction

Learn how to quickly build a custom blog with great SEO. Butter integrates with any Node.js server and templating engines like Mustache, Jade, and React. This guide uses the Express framework and EJS templates. Full working example code is available on Github.

If you need help after reading this, contact us via email, livechat, or book a time with to pair with one of our developers.

Display posts

To display posts we create a simple /blog route in our app and fetch blog posts from the Butter API. See our API reference for additional options such as filtering by category or author. The response also includes some metadata we'll use for pagination.

var express = require('express');
var butter = require('buttercms')('');
var app = express()

app.set('view engine', 'ejs');

app.get('/blog', renderHome)
app.get('/blog/p/:page', renderHome)

app.listen(3000)

function renderHome(req, res) {
  var page = req.params.page || 1;

  butter.post.list({page_size: 10, page: page}).then(function(resp) {
    res.render('index', {
      posts: resp.data.data,
      next_page: resp.data.meta.next_page,
      previous_page: resp.data.meta.previous_page
    })
  })
}

Next we'll create an EJS template for displaying our posts and pagination links. This guide uses EJS templates but Butter works with any templating engine like Jade, Mustache, and React. If you need help after reading this, contact us via email, livechat, or book a time with to pair with one of our developers.

<h2>Blog</h2>

<% posts.forEach(function(post) { %>
  <a href="/blog/<%= post.slug %>"><%= post.title %></a> by <%= post.author.first_name %> <%= post.author.last_name %>
  <br>
<% }); %>

<% if (previous_page) { %>
  <a href="/blog/p/<%= previous_page %>">Prev</a>
<% } %>

<% if (next_page) { %>
  <a href="/blog/p/<%= next_page %>">Next</a>
<% } %>

We'll also create an additional route for displaying individual posts:

app.get('/blog/:slug', renderPost)

function renderPost(req, res) {
  var slug = req.params.slug;

  butter.post.retrieve(slug).then(function(resp) {
    res.render('post', {
      title: resp.data.data.title,
      post: resp.data.data,
      published: new Date(resp.data.data.published)
    })
  })
}

The template for displaying a full post includes information such as author and publish date. See a full list of available post properties in our API reference.

<h2><%= post.title %></h2>

Published <%= published.getDate() %>/<%= published.getMonth()+1 %>/<%= published.getFullYear() %>

<% if (post.categories.length > 0) { %>
  in 
  <% post.categories.forEach(function(cat) { %>
    <a href="/category/<%= cat.slug %>"><%= cat.name %></a> 
  <% }); %>
<% } %>

<br>

<%= post.author.first_name %> <%= post.author.last_name %>

<div>
  <%- post.body %>
</div>

Categories, Tags, and Authors

Use Butter's APIs for categories, tags, and authors to feature and filter content on your blog:

app.get('/category/:slug', renderCategory)

function renderCategory(req, res) {
  var slug = req.params.slug;

  butter.category.retrieve(slug, {include: 'recent_posts'})
    .then(function(resp) {
      res.render('category', {
        title: resp.data.data.name,
        category: resp.data.data
      })
    })
}

See our API reference for more information about these objects:

RSS, Atom, and Sitemap

Butter generates RSS, Atom, and sitemap XML markup. To use these on your blog, return the generated XML from the Butter API with the proper content type headers.

app.get('/rss', function(req, res) {
  res.set('Content-Type', 'text/xml');

  butter.feed.retrieve('rss').then(function(resp) {
    res.send(resp.data.data)
  })
});

app.get('/atom', function(req, res) {
  res.set('Content-Type', 'text/xml');

  butter.feed.retrieve('atom').then(function(resp) {
    res.send(resp.data.data)
  })
});

app.get('/sitemap', function(req, res) {
  res.set('Content-Type', 'text/xml');

  butter.feed.retrieve('sitemap').then(function(resp) {
    res.send(resp.data.data)
  })
});

Comments

Butter doesn't provide an API for comments due to the excellent existing options that integrate easily. Two popular servies we recommend are:

Both products are free, include moderation capabilities, and give your audience a familiar commenting experience. They can also provide some additional distribution for your content since users in their networks can see when people comment on your posts. For a minimalist alternative to Disqus, check out RemarkBox or for an open-source option, Isso.

CSS

Butter integrates into your front-end so you have complete control over the design of your blog. The rich text editor allows for formatting that you'll want to make sure you have styled. The boilerplate CSS covers most cases:

.post-container {
  h1, h2, h3, h4, h5 {
    font-weight: 600;
    margin-bottom: 1em;
    margin-top: 1.5em;
  }

  ul, ol {
    margin-bottom: 1.25em;

    li {
      margin-bottom: 0.25em;
    }
  }

  p {
    font-family: Georgia, Cambria, "Times New Roman", Times, serif;
    font-size: 1.25em;
    line-height: 1.58;
    margin-bottom: 1.25em;
    font-weight: 400;
    letter-spacing: -.003em;
  }

  pre {
    display: block;
    padding: 1em;
    margin: 0 0 2em;
    font-size: 1em;
    line-height: 1.4;
    word-break: break-all;
    word-wrap: break-word;
    color: #333333;
    background-color: #f5f5f5;
    font-family: Menlo, Monaco,Consolas, "Courier New", monospace;
  }

  /* Don't float content on narrow screens */
  @media only screen and (min-width: 720px)  {
    .butter-float-left {
        float: left;
        margin: 0px 10px 10px 0px;
    }

    .butter-float-right {
        float: right;
        margin: 0px 0px 10px 10px;
    }
  }

  /* Image caption */
  figcaption {
    font-style: italic;
    text-align: center;
    color: #ccc;
  }

  /* Inline code highlighting */
  .butter-inline-code {
    padding: 2px 4px;
    font-size: 90%;
    color: #c7254e;
    background-color: #f9f2f4;
    border-radius: 4px;
    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
  }
}

Migration

To import content from another platform like WordPress or Medium, send us an email.

About Node.js

Node.js is a server-side JavaScript environment based on V8. Popular web development frameworks for Node.js include Koa, Express, and Hapi.

Blog Engine for these technologies and more

Ruby, Rails, Node.js, Python, ASP.NET, C#, Flask, Django, Go, PHP, React, Phoenix, Elixir

Get started now

Sign up with Google Sign up with Github
or