Random page feature for a static site with Eleventy
Code in this blog post was written with versions: eleventy: 2.0.1

Happy International RNG Day!

My favourite RNG comic from XKCD
The day is celebrated on a random day each year and last year’s roll landed us on this beautiful summer Friday. International RNG Day is a celebration of random number generation:
We often need numbers that are Random, for everything from games to encryption. RNG Day is an opportunity to learn more about Random Number Generation, and to have fun with it!
I wanted to celebrate it this year with a new feature on my website: a random blog post picker (or RBPP amongst friends).
When building in randomness into a static site, it’s important to be aware of when the randomness roll is performed.
If you build randomness into your templates or build step, you’ll generate a new outcome every build. Sometimes, this might be what you want and especially if you have automatic nightly builds for the site, it might work really well: every day the readers get a new random pick.
In my case however, I only build the site when I make changes: either I add new functionality (or fix old ones…) or I publish new or updated blog posts. This means that a build-time roll could be the same for a week or so between updates and that’s not a very fun or useful for our random blog post picker.
My code for the page at /random is as follows:
---
layout: layouts/page.njk
title: Random blog post
description: A random post from the hundreds published on my blog
---
<article>
<h1>{{ title }}</h1>
<noscript>
You need Javascript to spin the random generator. You can manually pick
something to read from <a href="/blog">blog index</a>.
</noscript>
<p>
This page will redirect to a random blog post from my blog in 5 seconds.
</p>
<script id="blog-posts" type="application/json">
[
{% for post in collections.posts %}"{{ post.url }}"{% if not loop.last %},{% endif %}{% endfor %}
]
</script>
<script>
const posts = JSON.parse(document.querySelector("#blog-posts").textContent);
const random = posts[Math.floor(Math.random() * posts.length)];
setTimeout(() => {
window.location = `${window.location.origin}${random}`;
}, 5000);
</script>
</article>
First, I have my frontmatter for the page. Then, I added a noscript tag to notify users who don’t have Javascript enabled that they can’t rely on this feature and must pick manually from the blog index.
In the first script
block, I dump all
the urls of my posts into a JSON array so my client-side Javascript can access
them.
Then, in the second block I parse that array into JSON and pick a random post. I then add a 5 second wait with setTimeout before directing the user into the new page.
If something above resonated with you, let's start a discussion about it! Email me at juhamattisantala at gmail dot com and share your thoughts. In 2025, I want to have more deeper discussions with people from around the world and I'd love if you'd be part of that.
Comments
Loading comments...
Continue discussion in Mastodon »