In my previous article I discussed how I added a Medium style read time indicator to my Ghost blog. And while I whole-heartedly recommend Ghost as a publishing medium, I recognise that a lot of people probably use a different blogging platform, such as Wordpress. Which is why I'll provide the steps to add this read time indicator to any website or blog.

Recap: How does the calculation work?

We should understand how the read time calculation works, before adding it to our website. This quote gives a good summary of the method Medium uses:

Read time is based on the average reading speed of an adult (roughly 275 WPM). We take the total word count of a post and translate it into minutes. Then, we add 12 seconds for each inline image. Boom, read time.
-- Medium

Adding this calculation to your page

In the previous article, I discussed the process of adding the read time indicator to my own Ghost blog. Some principles will be repeated in this article, but I will discuss them in a more general way.

1. Word count

The Countable.js library makes it very simple to count words on a web page or part of it. Adding the following code to the bottom of your page will make it possible to start counting words:

<script src="https://cdnjs.cloudflare.com/ajax/libs/countable/3.0.0/Countable.min.js"></script>
<script>
$(document).ready(function () {
    Countable.count($(".word-count")[0], function(counter) {
        console.log(counter.words);
    });
});
</script>

Note: This example makes use of jQuery, make sure you have it running on your page.

You might notice that the snippet above passes a certain div to the Countable.count() function. By adding this div to the page or page template, it is possible to specify which part should be counted. For example:

<body>
    ...
    <div class="word-count">
        ...countable content...
    </div>
    ...
</body>

2. Image count

To get the number of images in our word-count div, we only need to add this code:

var imageCount = $(".word-count").find("img").length;

3. Calculating read time

Now that we know the calculation algorithm, and we know how to find the required variables, we can put two and two together in the following code:

<script src="https://cdnjs.cloudflare.com/ajax/libs/countable/3.0.0/Countable.min.js"></script>
<script>
$(document).ready(function () {
    Countable.count($(".word-count")[0], function(counter) {
        var imageCount = $(".word-count").find("img").length;
        var seconds = counter.words / 275 * 60 + imageCount * 12;
        var minutes = Math.ceil(seconds / 60);
    });
});
</script>

4. Displaying the read time indicator

With the read time calculated, the next step is to display it somewhere. For this we will use the read-time span.

<span class="read-time"></span>
<script src="https://cdnjs.cloudflare.com/ajax/libs/countable/3.0.0/Countable.min.js"></script>
<script>
$(document).ready(function () {
    Countable.count($(".word-count")[0], function(counter) {
        var imageCount = $(".word-count").find("img").length;
        var seconds = counter.words / 275 * 60 + imageCount * 12;
        var minutes = Math.ceil(seconds / 60);
        $(".read-time").html(minutes + " min read");
    });
});
</script>

This will output the calculated read time where ever you put your read-time span.

5. Displaying the read time indicator in overviews

By following the process above, it is possible to add the read time indicator somewhere on your page, like I do at the top of this page. However, many blogging solutions such as Wordpress or Jekyll also display overviews of multiple blog posts as well. Ideally, we want the reader to see what the read time is before opening the post. To do this, we need to change the code we used before to accept multiple word-count divs.

<script src="https://cdnjs.cloudflare.com/ajax/libs/countable/3.0.0/Countable.min.js"></script>
<script>
$(document).ready(function () {
    $(".read-time").each(function(index) {
        var postContent = $(".word-count").get(index);
        var readTime = this;

        Countable.count(postContent, function(counter) {
            var imageCount = $(postContent).find("img").length;
            var seconds = counter.words / 275 * 60 + imageCount * 12;
            var minutes = Math.ceil(seconds / 60);
            $(readTime).html(minutes + " min read");
        });
    })
});
</script>

Note how the code now loops over all read-time spans, instead of just taking the first one. The calculator is now ready to calculate the read time of multiple articles, but we still need a way to add these corresponding word-count divs to the overview page.

Luckily, many blogging platforms use some sort of post loop in their themes, which makes it easy to add a read time indicator and a - hidden - word-count div to every post in the loop. I added the required pieces to example loops for Wordpress and for Jekyll below.

Wordpress

<?php while (have_posts()) : the_post(); ?>
     <div class="post">
         <h2 id="post-<?php the_ID(); ?>"><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
         <small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --> / <span class="read-time"></span> </small>
     </div>
     <div class="word-count" style="display: none;"><?php the_content(); ?></div>
<?php endwhile; ?>

Note the read-time span on line 4, and the word-count div on line 6.

Jekyll

<ul>
    {% for post in site.posts limit 4 %}
    <li>
        <span>{{ post.date | date_to_string }}</span> / <span class="read-time"></span> 
        <a href="{{ BASE_PATH }}{{ post.url }}">{{ post.title }}</a>
    </li>
    {{ post.content | strip_html | truncatewords:75}}
    <br>
    <a href="{{ post.url }}">Read more...</a>
    <br><br>
    <div class="word-count-div" style="display: none;">{{ post.content }}</div>
    {% endfor %}
</ul>

Note the read-time span on line 4, and the word-count div on line 10.

Also make sure the word-count divs do have the style="display: none;" attribute to hide them from the page, as we don't want the full post content on the overview pages.

These divs need to be added on all overview pages. Depending on your theme and blogging platform, these could be home pages, category pages, tag pages, author pages, and more. Make sure to check where you want the read time indicator to be displayed, and add the code snippets accordingly.

What if you don't have a fancy Blogging platform?

The nice thing about the platforms I mentioned above, is that it is easy to just get the content of a post by writing {{ post.content }} or the_content();. However, even if you're using a blogging platform that doesn't provide such luxuries, or if you're writing plain html files, it's possible to get the post content from a different page.

jQuery offers the nifty load() function to get content from a different page.

<span class="read-time"></span>
<div id="post-1" class="word-count" style="display: none"></div>
<script>
    $("#post-1").load("/posts/post_1.html .word-count");
</script>

This will load the contents of the word-count div in /posts/post_1.html into the word-count div with the id post-1 on the overview page. By doing this for all posts (each with a different id), the read-time can be calculated for every one of them.

Note: This code needs jQuery, so make sure to import it somewhere above this code.

Conclusion

I have shown you how to add a read time indicator to your blog posts, even when you're not using Medium or Ghost as your blogging platform. To reiterate, the most important steps are:

1. Add the following code to the bottom of any page where you want read time indicators

<script src="https://cdnjs.cloudflare.com/ajax/libs/countable/3.0.0/Countable.min.js"></script>
<script>
$(document).ready(function () {
    $(".read-time").each(function(index) {
        var postContent = $(".word-count").get(index);
        var readTime = this;

        Countable.count(postContent, function(counter) {
            var imageCount = $(postContent).find("img").length;
            var seconds = counter.words / 275 * 60 + imageCount * 12;
            var minutes = Math.ceil(seconds / 60);
            $(readTime).html(minutes + " min read");
        });
    })
});
</script>

2. Add corresponding read-time spans and word-count divs to the page

<span class="read-time"></span>
<!-- When on a main post page: -->
<div class="word-count"></div>
<!-- When on an overview page: -->
<div class="word-count" style="display: none"></div>

3. Make sure the post content is added to the word-count div on overview pages

Use the Wordpress or Jekyll examples, or look up how your blogging platform loads the content of a post. Alternatively, use the jQuery load() function to get the post content loaded into the overview pages.


If you enjoyed reading this article, please consider sharing it on Facebook, Twitter or LinkedIn. If you used this guide to add a read time indicator to your own site, or if you want to show what you did with it, leave a comment below!