Confluence: Create a custom word counter with JavaScript

Date: 2019-05-07 | confluence | javascript | blog | tutorial


Confluence is a great platform for creating and sharing content within an organization. It would be great if there was a way to dynamically display how much content is on a given page and the estimated amount of time it would take to read through it.


Depending on your Confluence instance setup, you will have the ability to insert arbitrary JavaScript via a <script /> tag in an HTML embed. Because this is arbitrary JavaScript, you will be able to modify the DOM as you would on any other web page. We can leverage this to create a custom word counter.

Note: If you are unsure whether you can use this solution in your Confluence instance, I recommend trying a simple HTML embed containing <script>console.log("script works")</script>. If you save this in the page and then refresh, you will see "script works" in the console (CTRL + SHIFT + I, in Chrome) if it's allowed, errors if it's not. If it's not, you can contact your sys admin about whether it can be changed.

Confluence pages have a pretty standard page layout so we're going to leverage that with a custom regex in order to get a basic word counter going. I have placed a snapshot of the code here for posterity but feel free to leave comments / make PRs to the snippet at the repo link below:

    const regex = new RegExp("[\s\n]([a-zA-z0-9])+[\s\n]", "g");
    const mainContentElement = document.getElementById("main-content");
    const wordMatches = mainContentElement.innerText.match(regex);
    console.log("number of words: ", wordMatches.length)
    var counterElement = document.createTextNode(Reading time: ~${parseInt(wordMatches.length / 200) + 1} minutes (${wordMatches.length} words));
    mainContentElement.insertBefore(counterElement, mainContentElement.firstChild);

Leave comments/make a PR for the snippet

Basically we

  • grab the html element within which Confluence displays the main page content
  • we match all whole words with regex
  • then we divide that length by 200 (an average human reads ~200 words / minute) and create a human-readable string based on that number inside an HTML text node
  • we insert that text node into the page before the first element within the main content section