Angelos Orfanakos

Add support for modification times in Gatsby

Note: This assumes you’ve already added support for Markdown pages.

What if you want to display the date and time a page or a post was last modified?

Gatsby exposes the date and time a file was last modified, as recorded in the filesystem, through its GraphQL API:

{
  markdownRemark {
    parent {
      ... on File {
        modifiedTime      }
    }
  }
}

However, Git does not retain file timestamp information. So if you ever git clone the repo (usually happens on deployment in services such as Netlify), the timestamp will be set to the current date and time. Obviously, this is not what we want.

The solution lies in the fact that Git records the date, time and modified files of each commit. So we can pull the necessary information from the last commit each file was modified in.

Open gatsby-node.js and create a gitAuthorTime node field:

const { execSync } = require('child_process');
exports.onCreateNode = ({ node, actions }) => {
  // ...

  if (node.internal.type === 'MarkdownRemark') {    const gitAuthorTime = execSync(      `git log -1 --pretty=format:%aI ${node.fileAbsolutePath}`    ).toString();    actions.createNodeField({      node,      name: 'gitAuthorTime',      value: gitAuthorTime    });  }
  // ...
};

Modify the page query of your template (e.g. src/templates/post.jsx) to fetch the gitAuthorTime node field:

query($slug: String!) {
  markdownRemark(fields: { slug: { eq: $slug } }) {
    # ...
    fields {      gitAuthorTime    }    # ...
  }
}

Finally, in the same template file, you can access gitAuthorTime through props:

import React from 'react';

const Post = props => {
  const { gitAuthorTime } = props.data.markdownRemark.fields;
  render (
    <p>Modified at: ${gitAuthorTime}</p>  );
}

export default Post;