Building a Personal Site with Gatsby

Part 4: Creating a List of Blog Posts

January 11, 2019

Note: This is a 9 part post that begins here: Part 1: Introduction and Setup

Now that we can generate blog posts from markdown files, we want to add a landing page at /blog that lists all of my posts in descending order. First create a bunch of placeholder posts with titles and dates in the frontmatter so we have something to list. Then create your src/pages/blog.js file and set up the component and GraphQL query:

src/pages/blog.js
import React from 'react';
import { graphql } from 'gatsby';
import Layout from '../components/layout';
const BlogPage = ({ data }) => {
  return (
    <Layout>
      <div className="post-list"></div>
    </Layout>
  );
};

export default BlogPage;

// Get all markdown data, in descending order by date, and grab the id, excerpt, slug, date, and title
export const pageQuery = graphql`
  query {
    allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
      edges {
        node {
          id
          excerpt(pruneLength: 250)
          fields {
            slug
          }
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            title
          }
        }
      }
    }
  }
`;

Our GraphQL query will return our markdown in descending order by date, with a formatted date, title, excerpt for previewing out posts, and our slug field that we can use to link to the individual blog post.

Now that we have our data, we can fill out the component:

src/pages/blog.js
import React from 'react';
import { graphql, Link } from 'gatsby';import Layout from '../components/layout';
const BlogPage = ({ data }) => {
  const posts = data.allMarkdownRemark.edges;  return (
    <Layout>
      <div className="post-list">        {posts.map(post => (          <div key={post.node.id} className="post-list__item">            <h2>{post.node.frontmatter.title}</h2>            <p>{post.node.frontmatter.date}</p>            <div className="post-list__excerpt">              <p>{post.node.excerpt}></p>            </div>            <Link to={post.node.fields.slug}>Read More</Link>          </div>        ))}
      </div>
    </Layout>
  );
};

We now have an ordered list of linked blog posts. Add a few more placeholder blog posts. In the next section we'll do some styling and add thumbnail images.