Creating this blog

by Kyle Peacock

After the .dev domains became available, I thought it would be fun to simply grab "peacock" as a top-level-domain. The domain was available, so I took the chance to buy it and set it up with a Gatsby site. I've been a superficial user of Gatsby for a while, but I hadn't done a deep dive into the inner Graphql layer or into its powerful integrations with CMS platforms. So, that's what this is.

This article is written on GraphCMS, where I created a one-to-many relationship between Developers and BlogPosts. I decided to follow a largely parallel path to the pattern that the folks from Contentful used on their starter, but where I was writing everything out by hand instead of using the boilerplate. I'm still a Contentful user, but their Gatsby integration actually felt a little janky to me, since it felt like there were a few extra steps that it made me step through to pull my data.

GraphCMS, on the other hand, really feels like a pure GraphQL query with an interface to configure the backend. It's a little less polished, but the API is as simple as you could want it to be. Plus, they have an excellent interface to allow you to play with their queries directly, which helped me in the setup process.

Screen Shot 2019-03-02 at 2.23.28 PM.png

The API explorer built into GraphCMS

The steps to get going are pretty straightforward:

  1. Set up the plugin following the GraphCMS Docs
  2. Set up a template for a blog post that can query blog posts by a unique field. (I'm calling it slug)
export const query = graphql`
  query BlogPostBySlug($slug: String!) {
    gcms {
      blogPosts(where: { slug: $slug }) {
        title
        content {
          markdown
        }
        markdownContent
        developer {
          name
        }
      }
    }
  }
`;

Query for the post

  1. Set up a gatsby-node.js file that iterates through blog posts and creates static entry points in order to allow every post to have a static entry
const path = require("path");

const { createFilePath } = require(`gatsby-source-filesystem`);

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions;
  if (node.internal.type === `GCMS`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` });
    createNodeField({
      node,
      name: `slug`,
      value: slug
    });
  }
};

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions;
  return graphql(`
    {
      gcms {
        blogPosts {
          slug
        }
      }
    }
  `).then(result => {
    result.data.gcms.blogPosts.forEach(post => {
      createPage({
        path: `/blog/${post.slug}`,
        component: path.resolve(`./src/templates/blog-post.js`),
        context: {
          // Data passed to context is available
          // in page queries as GraphQL variables.
          slug: post.slug
        }
      });
    });
  });
};

It took some trial and error, but the experience was informative and fun. For now I'm just injecting the content from their markdown editor, but I'm sure I'll find ways to extend it and make it a little more dynamic. It's a promising start for an impressively dynamic and sophisticated setup, and I feel more comfortable working in GraphQL after working through this build.