Blog post image

Beyond the traditional CMS stack

Article by

Dannie Håkansson

Published in

Web Development

I was tasked with creating the very website you’re visiting right now, containing a mix of static and dynamic content. It had to be fast, responsive, SEO friendly as well as have some kind of CMS powering it. Having only set up these types of websites with Wordpress, I was hoping I could build it with a more modern technology stack where I felt like I was more free to do what I wanted. With dynamo being a tech company and all, it only felt natural for us to be building the website ourselves, without the help of gigantic CMS solutions.

In Wordpress, a lot is to be gained by people being familiar with the CMS already. With our current website, people were accustomed to being able to layout blog posts themselves. From an editorial perspective, in Wordpress, you can do anything, anywhere.

The problem is, these traditional and monolithic systems introduce other issues such as scalability, security and legacy code. The legacy that these are built around will eventually come around and bite you since you will be in charge of hosting and installing the system yourself. This is without even mentioning that the coupling of presentation and data might lead your application severely inconsistent from view to view.

While in search for an alternative where the frontend would not be sacrificed and outsourced to the editors, CMS template and plugin creators, I stumbled across Contentful.

The headless CMS of Contentful

Contentful works in a manner where all of the content to be editable has to be decided first-hand, much like modelling relational database tables. The content types, as the datatypes are called here, are as flexible as you would want them to be, and you’re not locked into everything being a certain type, something that enables the data to be separated significantly from the visualisation of it. It never assumes anything about the way you will handle or present the data that you’re modelling. According to the their own wording, it is not actually a CMS, but a content infrastructure. That’s not to say they don’t bolster rich editing capabilities, because they most certainly do. You have options to configure the looks of the fields you decide that you want(think of them as different types of widgets). You can add custom text to each one of them, and apply very granular validations to each. Once you’re finished modelling, you create so called entries based on the content types, again much like records in a SQL based database.

It also provides powerful API capabilities, such as the Image API and Content Preview API, making it easy to scale your application to any type of device and platform. They have SDKs for any type of platforming preference you might have, and the best part of this actually the fact that all of this can be consumed with GraphQL, making everything very tailored to the specific needs of each application.

For those unfamiliar with GraphQL, it is a query language to be used by clients as an alternative to the REST API architecture. If you’ve ever had the issue of API developers spending way too much time extending endpoints to feature yet another filter or embedded object relation, or client developers receiving far too many data fields unrelated to their frontend, these are both issues GraphQL is trying to address by providing this query engine.

The new static site generator - GatsbyJS

I found a good match to Contentful in GatsbyJS, a new kid on the block of static site generators. It promised to be delivering crazy fast websites that were SEO friendly yet have a full fledged data-layer based on GraphQL. Static site generators are static sites per definition, but introduce dynamic elements in, usually, automatised builds pulling in content from different types of data sources(.md or .json files most commonly) in order to produce the final product. This product is then hosted on any server of choice to be delivered as basic HTML documents. The content is delivered as static, which means that for the user everything is there whenever the website has loaded initially.

The problem traditionally with this kind of approach has been to have updates to this content be made by non-technical people. Since everything that is actually deployed is static, how would we combine this with something like Contentful so that every time new content is created, we have an updated website? The answer lies in the Gatsby Contentful Plugin, where GraphQL queries will run for each page component:

query blogPageQuery {
  allContentfulBlogPost (sort: {
    fields: [publishedDate], order: DESC
  }) {
    edges {
      node {
        slug
        featuredImage {
          sizes(maxWidth: 380) {
          ...GatsbyContentfulSizes
          }
        }
        title
        summary {
          summary
        }
      }
    }
  }
}

This particular query is used on the blog overview page, which will visualize a featuredImage along with a title and summary. The slug is used to link to each individual blog post. As you can see, we have built in sorting in the actual query, based on the publishedDate of the blog post.

The Gatsby Contentful Plugin is one of many source plugins, which pull in data from either remote or local sources. The other type of plugins are the transformer plugins which transform the data that the source plugins provide. For instance, in order to visualize the text body you're reading right now, I've used the Gatsby Transformer Remark plugin in order to transform markdown into html:

query BlogPostQuery($slug: String!) {
    contentfulBlogPost(slug: {eq: $slug}) {
      textBody {
        childMarkdownRemark {
          htmlAst
        }
      }
    } 
  }

The key takeaway here is that within textBody we are now able to utilize the markdown fields. In this particular case we are interested in the abstract syntax tree conversion(Ast).

These data layer possiblities are the glue between Gatsby and Contentful, and is really where the power of this static site generator lies. The interesting thing about it is that all fetching of data is actually happening during build time as server side rendering.

Putting the data into components

The icing on the cake of Gatsby is that it is based on React.js. The output of the GraphQL query above can easily be utilized by any React component via its props:

const BlogPost = props => {
  const {
    htmlAst
  } = props.data.contentfulBlogPost.textBody.childMarkdownRemark

  return (
    <TextBody htmlAst={htmlAst} />
  )
}

Note: The component above is a so called Page Template Component, which will have the associated GraphQL data sent to its props automatically by Gatsby. Read more about the different component types here.

There’s no denying that every frontend developer has heard of the power of React at this point, and to have access to all that has been done within that community when working on a static website is simply amazing. Any npm package is one install away, and a streamlined webpack setup makes you get things done quicker.

Styling

I chose to use CSS Modules for pre-processing along with SASS, leveraging locally scoped selectors in order to not have to think about naming collisions in the global namespace. Regarding component frameworks, the design was quite minimalistic so I avoided any of those. I did think of the newer CSS Grid specification, but felt like none of the responsive behaviour we needed required it to be used. Instead I sprinkled in some CSS Flexbox and CSS Variables where necessary and called it a day.

I must say I was pleasantly surprised at how much is possible natively in the browser nowadays.

StandardJS

I've always been having trouble defining rules for code styling, be it .jshint, .jslint, .jsbeautify or the later .eslint configurations. The problem is everything becomes easily opinionated. Based on this I found StandardJS to be a great alternative that you can just drop into your project without any need for setup. It is based on ESLint which makes it great for writing more modern JavaScript. I personally use JetBrains WebStorm IDE and they actually have built-in support for StandardJS.

The hosting

Since we were building a static website, we had the flexibility of delivering it from any webserver. I was reading about using Netlify for Gatsby here and here and figured it must be worth a try.

With only a couple of minutes spent, I had:

  • A website connected to our private bitbucket repository, making automated deploys whenever I pushed to the master branch
  • HTTPS enabled with the help of Let's Encrypt
  • Messaging connected to slack whenever deploys were failing
  • Environment variables(like the Contentful API access tokens) being resolved within the node build
  • Contentful webhooks notifying Netlify when content changes, so that the site can be rebuilt

The last point is what really makes Gatsby and Contentful work in the end.

Before launching we made sure 301 redirects were apparent for relevant content we were moving from our old website, something also made easy with the _redirects file Netlify supports.

We have two websites running on Netlify now, one being a development server used for new functionality and previewing of content, and one for production and published content. Contentful provides preview links for each one of its entries, meaning we can send editors through these links onto our development website to preview their blog post. The only drawback is that each change in content will take a couple of minutes to finish building, but that's a minor issue in contrast to all of the benefits the static website approach brings.

The design

The design team at Dynamo, Mike and Anna, did a wonderful job of creating a new and fresh design which was delivered through Zeplin, making it super easy to communicate regarding big and small things. The design was very clean and consistent, and foremost very translatable to web.

Wrapping up

We now have a website were we're free to do whatever we want, something I believe will make our developers and content creators happier in the long run.

Links