DEV Community

Cover image for Add a Random Page Button to Hugo Site
Kevin
Kevin

Posted on • Originally published at kevinquinn.fun on

Add a Random Page Button to Hugo Site

I wanted to add a random button to one of my Hugo sites after remembering how handy it is on XKCD. Turns out it's a really simple process with Hugo, just need to generate a JSON file and then write a simple script to choose your random article.

What are we making?

Portfolio website with a randomizer button

How-to

1. Create JSON list of pages

Hugo conveniently lets you output JSON data, so we create one at the root which will get deploy alongside the rest of our static files. Couple caveats for this example:

  1. my filters are simple because the site only has one page archetype and I wanted all of them. You can definitely get mroe creative with Hugo's where and other functions.
  2. This index for site search was already in the theme I was using. If you just want the randomizer, you can drop all the extra data fields like tags and contents.
   # layouts/_default/index.json

   {{- $.Scratch.Add "index" slice -}}
   {{- range where site.RegularPages "Type" "in" site.Params.mainSections -}}
   {{ $date:= .PublishDate.Format "02"}}
   {{- $.Scratch.Add "index" (dict "title" .Title "date" $date "tags" .Params.tags "image" .Params.image "categories" .Params.categories "contents" .Plain "permalink" .Permalink) -}}
   {{- end -}}
   {{- $.Scratch.Get "index" | jsonify -}}
Enter fullscreen mode Exit fullscreen mode

I needed to add a small param in my config.toml, here's an article if you want to dive a bit deeper and understand more of what is going on.

[outputs]
    home = ["json", "html"]
Enter fullscreen mode Exit fullscreen mode

Prod JSON output

For reference, the JSON that the above Hugo code will end up outputting.

[
   {
     "categories": [
       "Developers"
     ],
     "contents": "text of the document",
     "date": "07",
     "image": "images/post/article-1.png",
     "permalink": "https://permalink",
     "tags": [
        "Software Development"
     ],
     "title": "Title of the most recent article"
   },
 ...
 ]
Enter fullscreen mode Exit fullscreen mode

2. Use JSON in an HTML page

You can add something similar to this in your HTML pages. I have this in a partial where the button is displayed on the page.

    <script>
     var searchIndexData = [];
     // fetch on page load from the search index
     let json_path = window.location.origin + '/index.json'

     fetch(json_path).then(function (response) {
        return response.json();
     })
     .then(function (data) {
        searchIndexData = data;
     })
     .catch(function (err) {
        console.log(err)
     });


     function sendToRandomArticle() {
     let randIndex = Math.floor(Math.random() * searchIndexData.length);
     let randArticle = searchIndexData[randIndex]['permalink'] + '?utm_source=RandomButton';
     window.location.href = randArticle;
     }

    </script>
    ...
    ...
    <button type="button" class="btn btn-primary" onclick='sendToRandomArticle()'>Random</button>
Enter fullscreen mode Exit fullscreen mode

That's it! Told you it was simple.

Top comments (0)