Juha-Matti Santala
Community Builder. Dreamer. Adventurer.

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!

xkcd comic 221 with code: int getRandomNumber() { return 4; // chosen by fair dice roll. guaranteed to be random. }

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

Comment by replying to this post in Mastodon.

Loading comments...

Continue discussion in Mastodon »