Eleventy Clock

I'm thrilled to announce Eleventy Clock, a brand new 720-page website that provides all the blood-pumping, nail-biting, chronometric exhilaration you'd expect from reading the current time. This isn't a single-page site that updates itself periodically—no, no!—but seven hundred twenty individual pages, painstakingly crafted to bring you every minute of every hour with utmost precision and accuracy.

Rendering of bright red flip clock on a white surface in front of a teal wall

It works like this. When you visit the landing page, a small blob of JavaScript crunches the current hour and minute according to the clock on your computer (phone, tablet, what have you), then redirects your browser to the static, nearly logicless page representing that time.

For example, if it were currently 11:11, you'd be redirected to https://eleventy-clock.netlify.app/11:11 and be greeted by a cheery, bright red flip clock sporting a pair of snake eyes.

But what good is a clock that's frozen in time? Not much. So this page has its own pinch of JavaScript that redirects back to the landing page when 11:12 is nigh. The landing page then redirects to /11:12, which eventually redirects back to the landing page... And on and on this goes, forever (or until you move on to something more worthy of your attention).

Now, asking a web browser to display the current time is fairly banal. (We can do it right here, in fact: . See? Nothing special.) So why go to all the trouble to build a site that tells time in such a backwards, uneconomical fashion?

The answer, as with all silly projects, is: to learn something new 📚


In case it's not obvious, allow me to reveal the big secret: I didn't create all 720 pages by hand. That would be bananas. Instead, I built Eleventy Clock while exploring pagination, a feature of its eponymous static-site generator that I hadn't used or even really understood until I saw this tweet from Vince Falconi:

It took me a good while to learn that 11ty’s pagination is not the pagination I thought it was.

I expected it to make next/previous and enumerated links, but no, it takes a collection and applies the template to each item. Powerful if your building from a non-file data source.

@vincefalconi • August 18, 2020

I had skimmed the pagination documentation before, but like Vince I assumed it was meant for building navigation from collections of pages and other data. You can use pagination to build Next and Previous links, of course. But after taking a closer look, I think the real power of Eleventy pagination is in its ability to generate static pages outside the traditional 1:1 relationship between templates and their output.

This got me thinking. What kind of data source could you use that pushes beyond what might typically be feasible or desirable to create by hand? Truth be told, my first instinct was 🌈 every hex color but building an array with 16,581,375 elements proved a formidable match for poor old Node, which fell over.

So I changed gears to a more manageable data set: 720 elements representing times from 1:00 to 12:59 in one-minute increments:

let times = [];

for( let h = 1; h <= 12; h++ )
	for( let m = 0; m <= 59; m++ )
		let time = {
			h: h,
			m: m.toString().padStart( 2, "0" ),

		times.push( time );

module.exports = times;
Adapted from src/site/_data/times.js

By adding pagination to the frontmatter of a single template:

    data: times
    alias: time
    size: 1
permalink: "/{{ time.h }}:{{ time.m }}/index.html"
Frontmatter adapted from src/site/pages/time.md

and specifying the data source as data: times, we can tell Eleventy to use the array that results from the global data file _data/times.js. Though pagination supports multiple data items per "chunk", since I just want a single hh:mm permutation per page I specify a size of 1.

(By default, we would reference the current pagination item in our template using pagination.items[0], but Eleventy supports aliasing as a convenience. Using alias: time, pagination.items[0] becomes just time. Nice.)

Finally, permalink brings everything together. Using the h and m properties of our "current pagination item" time alias, Eleventy builds a single page for each of the 720 array items exported by times.js.

Anticlimactically, that's it*! The true story of how a big-little site (whose only function is already served by every watch, smart phone, fax, pager, and stove in the world) came to be.

*Well, that's not really it. A few days of wrangling and wrestling CSS gradients, box-shadows, border-radii, and other tricks nicked from Lynn Fisher's awe-inspiring A Single Div followed. But aside from that...