Last modified date of Eleventy posts
I like Eleventy (11ty), but... there's always a "but", right? There have been a few things that I've struggled with. While 11ty has a ton of documentation, it's not always clear and concise. Answers on StackOverflow have been somewhat lacking. LLMs have been equally as misinformed.
One such problem I was trying to tackle is the matter of getting the last
modified date from posts. There is evidently some magic under the hood when
working directly with the date value, but that also changes date-based
permalinks every time the post is modified.
Not ideal.
Admittedly, there very well may be a way to handle this by doing some magic with the permalink structure. Since I don't have anything additional configured for permalinks, I didn't even think about it.
Front matters
When I first approached this, I added a last modified date value to the front matter of my post, as such:
---
title: Awesomest post ever
lastmod: 2025-07-20
---
Even more awesomer content...
Note the omission of date. I don't include date in my front matter because
it's derived from the filename. I've been naming my files this way for over a
decade, there's no chance in hell that I want to go back and change that.
Seriously, it's like 1,000 posts, and I wouldn't trust the robots to not screw
things up in epic fashion.
Awesome, with the lastmod date, I should be able to grab it like I do the
post's date. I did what came naturally, copied and pasted the date stuff and
s/date/lastmod/ and call it a day.
No dice. I restarted 11ty, still no value coming back.
As it turns out, referencing arbitrary front matter isn't the same as accessing certain magical bits from the front matter:
This is great: {{ page.date }}
This is not: {{ page.lastmod }}
Guessing somebody had decided that they didn't want accidental overwriting of
the magical stuff, thus, no ad-hoc front matter will pollute the page object.
While I never did find this documented in a way that I was able to grok, turns
out you just need to drop the page and access the front matter directly:
This is great: {{ page.date }}
This is also great: {{ lastmod }}
Problem solved, next issue. This is how I'm currently doing things on my blog. I like this method because I have control over the date that is going to be shown.
I tweak posts here and there. Not everything I do warrants a last modified date. In fact, if I were to add a last modified date across all posts, it would probably impact nearly all posts on the site. I'm not convinced this is a good thing, even if "search engines like to see updated content".
Automatically add a last modified date
My own gross curiosity led me down the rabbit hole of trying to figure this out, primarily because I've yet to find a site out there that seemed to outline how to do it.
11ty has some more magic under the hood called computed data.
The gist is that you can throw some code at a collection and have it calculate
things based on the post's data and front matter. This seemed perfect for adding
a lastmod value to every post.
To get started, you need to create an *.11tydata.js file for your collection.
I'm adding this value to my posts, so I slapped a posts.11tydata.js in my
posts directory:
const fs = require('fs');
module.exports = {
eleventyComputed: {
lastmod: (data) => {
try {
// Grab the modified time from the post file
const stats = fs.statSync(data.page.inputPath);
const mtime = stats.mtime;
// Grab the original post date and our modified date
const originalDate = new Date(data.page.date).toISOString().split('T')[0];
const modifiedDate = new Date(mtime).toISOString().split('T')[0];
// Only return the lastmod if it's different from the original date
if (modifiedDate !== originalDate) {
return mtime;
}
return null;
} catch (err) {
console.error(</span><span class="token string">Error checking mtime for </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">.</span>page<span class="token punctuation">.</span>inputPath<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">, err);
return null;
}
}
}
};
No idea why this code block refuses to play nice :*(
Now from within your template, you can check if lastmod is there, and if so,
you can use it:
{%- if lastmod -%}
<p>Last modified: {{ lastmod | utcDate }}</p>
{%- endif -%}
Wouldn't shock me if there's some subtle timezone nonsense going on in there. My
first pass was a bit bugged since the post date completely lacks a time. Since
mtime has both time and date, things were thrown off by a day.
I still favor the more hands on approach, but it's nice to know that Eleventy is flexible and allows you to really do some damage with calculating data on the fly.