Experiments with Gatsby
September 13, 2020
I follow GTD (Getting Things Done) to organise my work, and one of the key stages in the GTD workflow is that of Reflection. I do this through Weekly Reviews. The idea is to dedicate an hour every week to reflect on the week that was, and accordingly plan for the week ahead. It’s an opportunity to extricate yourself from the tactical and re-focus on the strategic. If you’ve ever found yourself floating from week to week, staying busy yet feeling unproductive and overwhelmed, I would strongly recommend the habit of doing Weekly Reviews. No matter your personal productivity system, it’s a truly impactful practice that can help improve your relationship with time.
I’ve iterated a fair bit on the format of my Weekly Reviews and over time, arrived at a practice that’s become a quasi-journaling exercise. I have prompts that get me thinking about how I feel about the past week, what went well and what didn’t, what my priorities should be for the upcoming week, etc. To add a bit of colour to the activity, I also make note of things I would like to associate with the past week, eg. things I’ve been watching, reading, listening to, etc. Over time, these records have grown to become like a private weeknotes repository.
Recently, when I came across Derek Sivers’ nownownow project, it struck me that I could share parts of my Weekly Review notes as a now page. This site is built with Gatsby, and the simplest way to accomplish this would be to just add a new page and keep updating it with the contents from my latest Weekly Review. But I didn’t want a typical now page, i.e. a static snapshot of what I’ve been upto lately. Instead I wanted to maintain an archive of each week’s notes, with the most recent post being the basis for the now page.
This also served as a good excuse for me to familiarise myself with all the Gatsby Magic powering this website. I’ve recorded the steps I followed to accomplish the desired setup using Gatsby’s Node API & Actions and thought of sharing it here for anyone interested.
The Strategy
To achieve this “journaling + status update” hybrid, I wanted a setup where I get two main things:
- A root “now” page: The
/nowroute always displays the content of the latest weekly review. - Archives: Every weekly review is preserved as its own page (e.g.,
/now/2020-09-06/).
Here is how I implemented it.
Step 1: Content Organization
I started by organizing my weekly reviews as individual markdown files in a specific directory: content/now. This keeps them separate from my main blog posts.
Each file represents a specific point in time. I use frontmatter to store structured data like what I’m reading or listening to, and the body for my free-form reflection.
---
date: "2020-09-06"
title: "Now: September 6th, 2020"
music: "Song Name"
musiclink: "https://..."
podcast: "Podcast Name"
podcastlink: "https://..."
book: "Book Title"
booklink: "https://..."
---
This week was focused on...Step 2: Configuring the Data Source
To make Gatsby aware of these files (and also to distinguish them from my regular blog posts) I added a new instance of gatsby-source-filesystem to gatsby-config.js.
gatsby-source-filesystem is a Gatsby plugin that creates File nodes from files in your filesystem. These nodes are then available to be queried via Gatsby’s GraphQL API, which is what Gatsby uses as its data layer to pull data into components.
// gatsby-config.js
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/content/now`,
name: `now`, // This name is crucial for filtering later
},
},By giving this source the name now, I can later filter specifically for these files in my GraphQL queries using filter: { fields: { sourceName: { eq: "now" } } }.
Step 3: Generating the Archive Pages
This is where gatsby-node.js comes in. This file is run once in the process of building the site. You can use it to create pages dynamically, add nodes in GraphQL, or respond to events during the build lifecycle.
I use the createPages API to programmatically generate a page for every single entry in content/now.
The process involves:
- Querying: Fetching all markdown files where
sourceNameis “now”. - Looping: Iterating through the results.
- Creating: Calling
createPagefor each one.
// gatsby-node.js
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
const nowPost = path.resolve(`./src/templates/now-post.js`)
return graphql(`
{
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC },
filter: { fields: { sourceName: { eq: "now" } } }
) {
edges {
node {
fields { slug }
}
}
}
}
`).then(result => {
const posts = result.data.allMarkdownRemark.edges
posts.forEach((post, index) => {
// Logic to determine previous/next posts for navigation
const previous = index === posts.length - 1 ? null : posts[index + 1].node
const next = index === 0 ? null : posts[index - 1].node
createPage({
path: `/now${post.node.fields.slug}`, // e.g. /now/my-post
component: nowPost,
context: {
slug: post.node.fields.slug,
previous,
next,
},
})
})
})
}I used a dedicated template (src/templates/now-post.js) to render these historical pages, complete with “Previous” and “Next” navigation links passed via the context.
Step 4: The Main “/now” Page
For the main /now page itself, I didn’t need to use gatsby-node.js. Instead, I created a standard page component at src/pages/now.js.
The key here is in the page query. It explicitly fetches the most recent post from the “now” collection.
// src/pages/now.js
export const pageQuery = graphql`
query {
allMarkdownRemark(
sort: {fields: [frontmatter___date], order: DESC},
filter: {fields: {sourceName: {eq: "now"}}},
limit: 2
) {
edges {
node {
# ... requests title, date, html body, etc.
}
next {
fields { slug }
}
}
}
}
`By sorting locally by date DESC and taking the first result, this page always renders the latest update. I also grab the next node (which in this sorted list effectively acts as the “previous” chronological post) to provide a link back into the archives.
Conclusion
This two-pronged approach accomplishes both my objectives: a dynamic “now” page faithful to the original spirit of now pages, and a permanent archive of my weekly reviews that acts as a journal of sorts.
Debatably pointless thoughts, pointlessly debated by Akaash Patnaik. He also uses other platforms to similar effect:
