During the last days, I was intrigued by the possibilities of integrating custom JavaScript for interactive applications into Hugo static websites. In this short tutorial, I am documenting how I hosted an interactive word and character counter (useful during applications, often faster than writing local documents and using the terminal) on my website here.
Write your JavaScript application
In my case, I wrote an improved version of this word counter.
var count = document.getElementById('count');
var input = document.getElementById('input');
var globalWordCounter = 0;
var WORD_LIMIT = 100000;
input.addEventListener('keydown', function(e) {
if (globalWordCounter > WORD_LIMIT && e.code !== "Backspace") {
e.preventDefault();
return alert("You have reached the word limit");
}
});
input.addEventListener('keyup', function(e) {
wordCounter(e.target.value);
});
function isWord(str) {
var alphaNumericFound = false;
for (var i = 0; i < str.length; i++) {
var code = str.charCodeAt(i);
if ((code > 47 && code < 58) || // numeric (0-9)
(code > 64 && code < 91) || // upper alpha (A-Z)
(code > 96 && code < 123)) { // lower alpha (a-z)
alphaNumericFound = true;
return alphaNumericFound;
}
}
return alphaNumericFound;
}
function wordCounter(text) {
var text = input.value.replace(/\n/g, " ");
var charCount = 0;
for (var i = 0; i < text.length; i++) {
charCount++;
}
text = text.split(' ');
var wordCount = 0;
for (var i = 0; i < text.length; i++) {
if (!text[i] == ' ' && isWord(text[i])) {
wordCount++;
}
}
var wordcharCount = wordCount.toString() + " Character Count: " + charCount.toString();
globalWordCounter = wordcharCount;
count.innerText = wordcharCount;
}
Save the js script to your Hugo project
In my case, I save the file under /static/js/wc.js
so that
the file gets rendered into /js/wc.js
in the /docs/
folder
where my website is hosted. You can check the location of
your script through accessing
yourwebsite.com/js/wc.js
Now, all html files can source your script with
<script src="/js/wc.js"></script>
Build a cool Hugo shortcode in order to flexibly embed the script in markdown syntax
In my case, I write js_wc.html
to /themes/min-night/layouts/shortcodes/
The contents of that file are:
<h2>Word Count: <span id="count">0</span></h2>
<textarea id="input" rows="10"></textarea>
<script src="/js/wc.js"></script>
Now, I can reference this html chunk anywhere using (remove the space between the two curly brackets, I needed to insert spaces such that the short code does not get rendered):
{ {< js_wc >} }
Write a post using that shortcode
Once all is set up, this is arguably the easiest step (if all is done correctly, the markdown document for my word counter literally just includes a head and the shortcode).
I could even render the application right here:
Word Count: 0
Final thoughts
JavaScript applications are a nice motivator for wrapping your mind around Hugo shortcodes. Understanding Hugo shortcodes will not only enable you to host cool JavaScript applications on your website, but also make you understand how your Hugo theme works, so that you can alter your theme to your custom needs as well.