Ghost  / Development  / Tips & Tricks
Reading Time:

How to add 'reading time' to your articles

It can be very useful for readers to know how much time they can expect to spend on an article before they engage. That's why I decided to add an estimated reading time to my blog. It will take approximately 3 minutes to read this article and find out how I implemented that.

How fast does the average person read?

Before going all technical and start inserting scripts in webpages, we need to find out how fast the average (adult) person reads.

Research done in 2012 measured the speed at which subjects read aloud. They also found that the average reading speed varies per language. For English, the language for this blog, the average lies around 228 (± 30) words per minute (Table 2 in the article). This is the number we will use for our calculations later on.

Adding the reading-time

In order to add the reading-time estimation to a page, we'll go through the following steps:

  1. Add an empty tag as placeholder where the reading-time should be displayed.
  2. Create or locate an HTML-tag surrounding the post's contents (i.e. the words that need to be counted).
  3. Calculate the reading-time and place the results inside our placeholder-tag

Note: The page you want to make your modifications to, is the page displaying the contents of your articles. In Ghost, the file you'll be looking for is called post.hbs, which is the page I will be modifying in this example.

Step 1 Add an empty placeholder-tag

The first step for adding a reading-time estimation to a page is to find the location you want this indication to show. For my pages it is next to the publication-date right before the title.

Add an HTML-tag (div for example) in which the reading-time should be placed. In order to find it later in our script, I gave the tag the class 'reading-time'. This makes it easy to add some additional styling as well. In my case the code looks like follows:

<article>
   ... snip ...
      <div class="reading-time"></div>
   ... snip ...   
</article>

Step 2 Locate the article contents

In Ghost, the contents of an article are included with the {{content}} helper. On my page, this helper is contained within a section with the class post-full-content:

<section class="post-full-content">
   {{content}}  
</section>

This means that we can use the class name post-full-content to retrieve the contents of the text later in the calculation script.

Step 3 Calculate the reading-time

Now add the following piece of javascript to the bottom of the page (between <script></script> tags of course):

$(function () {
    var txt = $(".post-full-content")[0].textContent,
    
    wordCount = txt.replace( /[^\w ]/g, "" ).split( /\s+/ ).length;

    var readingTimeInMinutes = Math.floor(wordCount / 228) + 1;
    var readingTimeAsString = readingTimeInMinutes + " min";
    
    $('article .reading-time').html(readingTimeAsString);
});
  • The jQuery-code inside the $(function() { ... }) will only run once the DOM is ready for Javascript code to execute (see the jQuery api reference for details on the .ready() function).
  • Line 2 retrieves the text contained in the 'post-full-content' section of the page and stores it inside the txt-variable.
  • Word count magic happens in line 4, where the text is processed in 3 steps:
    1. Remove all non word-characters, (i.e. not alphanumeric or underscore).
    2. Split the text by the space-character (i.e. the actual words in the text). This returns an array of words.
    3. Count the number of entries in the array (i.e. words in the text).
  • Line 6 divides the number of words by 228, as we decided 228 would be the average amount of words per minute an adult would be able to read.
  • Line 7 finalizes the text to be displayed by adding the word ' min' (for 'minutes') to the reading time.
  • Line 9 substitutes the html inside the reading-time class within the article tag, with the text to be displayed.

After this is done, you might want to do some extra styling on the reading-time class in your CSS to integrate it nicely inside your website.