Day 5 again - Making dates readable in 11ty with Luxon.

Bonus post today because the date strings are driving me nuts.

I like a readable date. After all, I'm human and seeing a date as a string adds more effort than should be required to read a date. I get that these dates are formatted for computer parsing so I'm not complaining.

[Mon Oct 19 2020 01:00:00 GMT+0100 (British Summer Time)]

Case. In. Point.

So I want to convert this date into something readable like 19th Oct 2020.

I was digging around one of the 11ty example projects and spotted something in their .eleventy.js file.

eleventyConfig.addFilter("readableDate", dateObj => {
  return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat("dd LLL yyyy");
});

And

// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string
eleventyConfig.addFilter('htmlDateString', (dateObj) => {
   return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('yyyy-LL-dd');
});

So looking at this, we'll need to adapt our .eleventy.js file to use the configuration API. This exposes the config as a function instead of an object.

The configuration docs on 11ty explain this a lot better than I ever could but I've followed these steps and adapted my config file to use the configuration API.

It's worth double checking your terminal to see if it's running OK or whether it's throwning up any errors.

Once we've moved the config file to use the API and we've slipped our readableDate function in, we should be able to add the function in when we call our dates and it should be readable right?

Wrong

So I've just refreshed my page locally and terminal has kicked up an error.

ReferenceError: DateTime is not defined

Whilst looking at the filter we added in from above, it's clear that it's trying to grab a date from somewhere that we've yet to define.

Looking back over the example config file, I've noticed a const call at the top of the config page.

const { DateTime } = require("luxon");

aaahh, I've seen luxon mentioned before as a plugin to have readable dates in 11ty. Let's have a little look at Luxon shall we?

A powerful, modern, and friendly wrapper for Javascript dates and times.

Nice.

Luxon is a JS wrapper that we can install via npm on the command line. Open up a new terminal window, cd to your sites directory and install Luxon

npm install luxon

Now back on our .eleventy.js config file, let's set luxon up there as a const.

const { DateTime } = require("luxon");

Luxon will now fire into action whenever DateTime is called.

Heading back to the example 11ty base blog github and a quick review of how they've set up their post links, I can see they've wrapped the dates in <time> tags. I previously done this as a <span> but time makes much more sense so I've swapped out my code to mimic the example.

<time class="postlist-date" datetime="Invalid DateTime">Invalid DateTime</time>

So what this is doing is setting the datetime value to the date of the post formatted as HTML. A quick flick back to our config and the htmlDateString function reveals that it'll take the date and convert it to yyyy-LL-mm or 2020-10-19. And then the code is displaying the readable date, which is formatted as dd LLL yyyy which displays as 19 Oct 2020, much better.

Conclusion

Woah, a bit more JS wrangling than I had anticipated but it works!

It'd be lovely if 11ty came with a readable date function rolled in, but then it's not strictly a blogging platform. I can't see a readable date function being required on most of the use cases for 11ty so I can see why it's not bundled in.

I can see me using 11ty a fair bit in the future though, so I'll keep this page handy :)