Show reading time & progress

Show reading time & progress

Reading time and progress bars give your readers a sense of what they’re getting into. Is this an epic long read or a quick jaunt? With Ghost, it’s easy to create these signposts by adding the reading time to your posts or showing your reader’s progress through an article.


In this tutorial, we’ll see how to add reading times to your Ghost theme and use JavaScript (JS) to update the reader’s progress in real-time. (Just look at the top of this page while you're reading for a demo.)

Reading time

Letting your readers know how long it’ll take to read an article is quite simple in Ghost. The reading_time helper outputs a customizable, calculated reading time of your content.

Post card showing a 55 min reading time

Add {{reading_time}} to your Ghost template to output x min read.

{{! Ensure you're in a post context }}
{{#post}}
	{{reading_time}}
	{{! outputs: 3 min read }}
{{/post}}

It’s also possible to customize the helper’s output.

{{! Ensure you're in a post context }}
{{#post}}
	{{reading_time minute="Only a minute" minutes="Takes % minutes"}}
	{{! outputs: Takes 3 minutes }}
{{/post}}

The minute attribute defines the value to use when reading time is calculated to be one minute or less. minutes defines the value to use when reading time is greater than a minute. (% is a variable that will be replaced with the number of minutes.)

And that’s all there is to it – you’re now an expert with the reading_time helper 🤓

Our docs are a great reference for the reading time helper and include some extra information about how reading time is calculated – for example, images count toward the reading time! You can also check out how we use reading time in the Casper theme.

Ghost Handlebars Theme Helpers: reading_time
Render the estimated reading time of a post in your Ghost publication with this handlebars helper ⚡️ Read more about Ghost themes!

Show reading progress

With reading time, the reader knows how long it will likely take to read your post, but what if we could provide real-time status as they read the article? By adding some custom HTML, CSS, and JS – this is also possible.

Add the progress bar element

The first step is to add the <progress> element to the post template. We’ll add a class to make it easier to style in the next step. In post.hbs, add the following code block after {{!< default}}:

<progress class="reading-progress" value="0" max="100" aria-label="Reading progress"></progress>

The progress element shows the completion status of a task. It could be the progress of a file upload, for example. In our case, it’s the reader's progress through the article.

Style the progress bar

By default, the progress bar will be styled by the user’s browser. To maintain a consistent design, we’ll add some CSS to style the progress bar.

In Code Injection Site Header, add this code:

<style>
.reading-progress {
  position: fixed;
  top: 0;
  z-index: 999;
  width: 100%;
  height: 5px; /* Progress bar height */
  background: #c5d2d9; /* Progress bar background color */
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none; /* Hide default progress bar */
}

.reading-progress::-webkit-progress-bar {
  background-color: transparent;
}

.reading-progress::-webkit-progress-value {
  background: var(--ghost-accent-color); /* Progress bar color */
}
</style>

Comments above indicate the options you’d most likely want to change. The progress bar's color is set to the accent color as defined in Ghost Admin.

Make the progress bar dynamic

The final component is to add the JS that will dynamically update the progress bar as the reader scrolls through the article. Add this code to default.hbs right before ghost_foot:

{{#is "post"}}
  <script>
    const progressBar = document.querySelector('.reading-progress');

    function updateProgress() {
      const totalHeight = document.body.clientHeight;
      const windowHeight = document.documentElement.clientHeight;
      const position = window.scrollY;
      const progress = position / (totalHeight - windowHeight) * 100;
      progressBar.setAttribute('value', progress);
      requestAnimationFrame(updateProgress);
    }

    requestAnimationFrame(updateProgress);
  </script>
{{/is}}
default.hbs

That’s it! Zip up your theme and upload it to your Ghost site. Hop on over to a post and start scrolling to see your real-time progress bar in action 💥

Demo

0:00
/

Summary

This tutorial walked through two ways to let readers know just how long (or short) that post is on your Ghost site. Being able to add reading time and progress to a theme means you're well on you're way to becoming a top-notch Ghost developer.

We’re eager to see your progress (bars), so come on over to our Forum to show off 😉

On this page Introduction

How was the tutorial?

Be the first to know.

Join the Ghost developer community — sign up to get early access to the latest features, developer tools, and tutorials.

No spam. Once a month. Unsubscribe any time.