Gatsby: Modification times 💩

Created on 7 Nov 2018  ·  7Comments  ·  Source: gatsbyjs/gatsby

Summary

I'm using the following snippet to automatically add file modification times to certain pieces of content on our site:

fs.statSync(node.fileAbsolutePath).mtime

I was scratching my brain at this one for a while, because my local builds do show differences in those dates, but on production they all show the last deploy date.

I did some digging and it looks like this is a “git” issue https://stackoverflow.com/a/48427454/1026742 (that answer is from someone that works at Netlify).

What I'd ideally like to do is have a hook that runs each time a file is saved. In my case, from the Netlify CMS UI, but also locally; where I could update a frontmatter field that I'd tag as something like, updatedDate. I looked at the Node API and didn't see anything that'd fit my needs, but I may also be missing something.

Anyone have tips on the best way to tackle this; OR (hopefully) something simple I'm missing that'd make this easier for content creators on my team? Thanks!

question or discussion

Most helpful comment

Just adding some info for anyone who finds this via google (like me!):

  • You could just update the mtime on all the files. e.g., StackOverflow's _Restore a file's modification time in Git_.
  • You could fetch the author time of the last commit: git log -1 --pretty=format:%aI -- package.json
  • You could fetch the author time of the most recent commit: git log --pretty=format:%aI -- package.json | sort | tail -n 1

    The most recent commit can be different depending on how things are merged. For a single user blog that nobody submits PRs for (like mine) then the last commit is sufficient.

  • If you prefer the committer time, use %cI instead of %aI.

    The author time is when the change was authored and the committer time is when the change was applied to git.

All 7 comments

To put this a bit more generally since I know ☝️is a mouthful; is there a hook "on-save" of content that I can use to modify frontmatter data?

Not sure exactly what type of content you're trying to augment, but this sounds like a good use case for onCreateNode

The general idea would be something like this:

exports.onCreateNode = ({ actions: { createNodeField }, node }) => {
  const type = node.internal.type;
  if (type === 'MarkdownRemark') {
    createNodeField({
      node,
      name: `modifiedTime`,
      value: `compute_value_you_want_here`
    })
  }
}

this will create a query-able fields object, e.g.

query GetAllMarkdownContent {
  allMarkdownRemark {
    edges {
      node {
        fields {
          modifiedTime
        }
      }
    }
  }
}

Hey @DSchau thanks for the reply. That's actually where I'm doing it 😄

Great that I'm following a recommendation, but sucks that the mtime is basically moot being pulled from a repo on Netlify and built on theirs.

What about adding an explicit creationDate field in the frontmatter? If it's a git issue, I'm not sure we can work around that in Gatsby apart from something manual like setting the metadata explicitly!

Yep, I've got a date field in there already for creation, but we'd like to use a modification date for things like tutorials; where context of when it was last updated could be helpful. I guess since there isn't any persistence on the file I can count on, it sounds like a manual field would probably be best.

Definitely not an issue with Gatsby, but something I figured would be worth asking. Thanks for chatting with me on this one!

Just adding some info for anyone who finds this via google (like me!):

  • You could just update the mtime on all the files. e.g., StackOverflow's _Restore a file's modification time in Git_.
  • You could fetch the author time of the last commit: git log -1 --pretty=format:%aI -- package.json
  • You could fetch the author time of the most recent commit: git log --pretty=format:%aI -- package.json | sort | tail -n 1

    The most recent commit can be different depending on how things are merged. For a single user blog that nobody submits PRs for (like mine) then the last commit is sufficient.

  • If you prefer the committer time, use %cI instead of %aI.

    The author time is when the change was authored and the committer time is when the change was applied to git.

Just adding something else to future Googlers:
Saber now has this solved elegantly via a plugin! https://github.com/saberland/saber/tree/master/packages/saber-plugin-git-modification-time

Was this page helpful?
0 / 5 - 0 ratings

Related issues

benstr picture benstr  ·  3Comments

3CordGuy picture 3CordGuy  ·  3Comments

andykais picture andykais  ·  3Comments

dustinhorton picture dustinhorton  ·  3Comments

theduke picture theduke  ·  3Comments