A reading-time label gives visitors a quick way to judge whether an article fits their available time. This guide shows how to calculate reading time, choose a words-per-minute assumption, display the result accessibly, and maintain the implementation across WordPress, Shopify, and static sites.
Overview
The basic reading-time formula is simple:
Reading time in minutes = word count ÷ words per minute
Round the result up to a practical whole number for display. For example, an article with 1,100 words at a benchmark of 220 words per minute produces 5 minutes. A label such as “5 min read” is easier to scan than “4.99 minutes.”
Reading time is an estimate, not a promise. People read at different speeds, and technical articles, legal explanations, tables, code, quotations, and images can change the time required. Use the label as a planning aid rather than a precise measurement.
For a broader publishing workflow, pair this calculation with a complete blog publishing workflow. Reading time is most useful when it appears alongside other editorial signals, such as the publication date, update date, category, or article format.
Reference formulas
| Input or method | Formula or rule | Best use |
|---|---|---|
| Word-based estimate | Words ÷ chosen WPM | Most standard blog posts |
| Short informational post | Words ÷ 200, rounded up | Accessible default when you want a conservative estimate |
| General editorial post | Words ÷ 220, rounded up | A consistent site-wide publishing convention |
| Dense or technical post | Words ÷ 180, rounded up | Articles with code, specialist vocabulary, or complex instructions |
| Fast-scanning format | Words ÷ 250, rounded up | Short, familiar, highly scannable content |
| Character-based fallback | Characters ÷ 5, then ÷ WPM | When a system provides characters but not words |
The WPM values above are editorial assumptions, not universal measurements. Pick one default, document it, and use it consistently. If your site publishes very different formats, assign a separate rule to long-form guides, tutorials, and code-heavy documentation.
How to estimate
- Define the content boundary. Decide whether the calculation includes the title, introduction, captions, pull quotes, related links, footnotes, and comments. For most blogs, calculate the main article body and exclude navigation, sidebar text, author biographies, and related-post modules.
- Count the words. Use the CMS word count if it accurately represents the published article. Otherwise, extract the rendered article text and count word-like sequences.
- Select a WPM benchmark. Use one site-wide value for consistency or use a documented value by content type. A technical tutorial may deserve a slower assumption than a short news-style update.
- Divide and round up. Rounding up avoids displaying “0 min read” for a short post and gives readers a simple planning estimate.
- Display the result near the title. Common placements include the metadata row below the headline, the article header, or a compact summary panel. Keep the label close to other orientation information.
- Test the published output. Check mobile and desktop layouts, keyboard navigation, zoom, screen-reader output, translations, and articles with zero or very few words.
JavaScript for a rendered article
This client-side pattern counts text inside an article element and writes a reading-time label into a separate element. It uses a conservative 220 WPM assumption; change the value to match your editorial policy.
const article = document.querySelector('[data-reading-content]');
const output = document.querySelector('[data-reading-time]');
const wordsPerMinute = 220;
if (article && output) {
const text = article.textContent.trim();
const words = text ? text.split(/\s+/u).length : 0;
const minutes = Math.max(1, Math.ceil(words / wordsPerMinute));
output.textContent = `${minutes} min read`;
}
Use markup similar to this:
<span data-reading-time aria-label='Estimated reading time'></span>
<article data-reading-content>...article content...</article>
Client-side calculation is convenient, but the label may appear late or remain empty if JavaScript is blocked. For important metadata, server-side or build-time rendering is usually more resilient.
PHP for a WordPress theme
A theme-level function can calculate the estimate from post content before it is displayed. This example removes shortcodes and HTML, decodes entities, counts Unicode word sequences, and returns a complete label.
function site_reading_time( $content, $wpm = 220 ) {
$content = strip_shortcodes( $content );
$content = wp_strip_all_tags( $content );
$content = html_entity_decode( $content, ENT_QUOTES, 'UTF-8' );
$words = preg_match_all( '/[\p{L}\p{N}]+/u', $content, $matches );
$words = $words ? $words : 0;
$minutes = max( 1, (int) ceil( $words / $wpm ) );
return sprintf(
_n( '%d min read', '%d min read', $minutes, 'your-text-domain' ),
$minutes
);
}
Place the function in the appropriate theme or site functionality file, then call it near the post title with the post content. Test translation behavior in your site’s configured languages, and avoid counting content that is hidden from the reader but still present in the source.
Liquid for Shopify
Where the available Liquid filters provide a reliable word count, the display can remain server-rendered:
{% assign words = article.content | strip_html | split: ' ' | size %}
{% assign wpm = 220 %}
{% assign reading_minutes = words | plus: wpm | minus: 1 | divided_by: wpm %}
{% if reading_minutes < 1 %}{% assign reading_minutes = 1 %}{% endif %}
<span aria-label='Estimated reading time'>{{ reading_minutes }} min read</span>
Liquid behavior can vary by platform context and theme implementation. Verify the result against several real articles, especially content containing repeated spaces, markup, lists, and non-Latin writing systems.
Markdown or static-site implementation
Static sites can calculate reading time during the build. A simple front-matter convention keeps the policy visible:
---
title: Example article
reading_wpm: 220
---
{{ content | reading_time: page.reading_wpm | append: ' min read' }}
The exact filter name depends on the static-site generator. If no reading-time filter exists, calculate the value in the build script and pass it to the template. Build-time output avoids layout shifts and does not depend on the visitor’s browser.
Inputs and assumptions
A dependable reading-time calculator needs more than a division formula. Record these decisions in your editorial documentation:
- Content scope: State whether headings, lists, tables, captions, code, and pull quotes are included.
- Words-per-minute policy: Choose a default and explain when editors may use a different value.
- Rounding: Round up to the next whole minute for a simple label. Do not show decimals unless your audience needs more precision.
- Minimum value: Display “1 min read” rather than “0 min read” for a published article with content.
- Language handling: Word boundaries differ across languages. A whitespace split is a practical fallback, not a universal linguistic solution.
- Accessibility: Use real text, sufficient contrast, meaningful spacing, and a visible label. Do not rely on color or an icon alone. If an icon is decorative, hide it from assistive technology.
- Localization: Translate the complete phrase, including plural behavior and number formatting, rather than concatenating fragments in a way that may be unnatural in another language.
Compare implementation choices before adding another blogging tool or plugin:
| Approach | Performance | Accessibility and localization | Maintenance tradeoff |
|---|---|---|---|
| Theme or template code | Usually efficient because output is server-rendered | Full control over text, semantics, and translations | Requires development access and theme maintenance |
| CMS plugin or app | Depends on implementation and added assets | Check whether it outputs real text and supports your languages | Convenient, but compatibility and pricing can change |
| Client-side JavaScript | Adds browser work and can delay the label | Needs careful handling for no-script and assistive-technology cases | Easy to customize, but browser changes and theme scripts need testing |
| Static-site build step | Fast at runtime and avoids layout shifts | Localization depends on template support | Stable once configured, but requires a rebuild after content changes |
For related text utilities, a reading time calculator can provide a quick editorial check, while a character counter is useful when another publishing system supplies character totals instead of word totals.
Worked examples
Example 1: a standard blog post
An article contains 1,100 words. Using 220 WPM:
1,100 ÷ 220 = 5 minutes
Display: 5 min read.
Example 2: a dense tutorial
A technical guide contains 1,850 words and includes code blocks and configuration steps. Using 180 WPM:
1,850 ÷ 180 = 10.28 minutes
Round up and display: 11 min read. This does not mean every reader will spend 11 minutes on the page; it signals that the guide requires more time than a short article.
Example 3: a character-only input
Suppose an export reports 6,600 characters including spaces. Using the rough rule of five characters per word:
6,600 ÷ 5 = 1,320 estimated words
At 220 WPM, the estimate is 1,320 ÷ 220 = 6 minutes. Label this as an estimate and use an actual word count whenever one is available. Character-to-word conversion is especially approximate for languages, code, URLs, and content with unusually long or short words.
When editing the article, use a readability editing guide alongside reading time. Shorter sentences and clearer headings may improve the experience without necessarily reducing the total word count.
When to recalculate
Recalculate reading time whenever the article changes materially. A small typo correction rarely matters, but adding a section, removing a case study, inserting a long code example, or changing the content format can change the estimate enough to update the label.
Use this maintenance checklist:
- Recalculate after substantial edits, article merges, content audits, or template changes.
- Review the WPM assumption quarterly, or sooner if new reading-speed research changes your editorial guidance.
- Review accessibility and localization guidance quarterly and after changing your design system.
- Check plugin or app compatibility after major CMS releases and whenever a widely used option changes pricing or receives significant critical feedback.
- Retest code snippets when browser behavior, theme frameworks, build tools, or platform filters introduce breaking changes.
- During a redesign or A/B test, compare placement, wording, visibility, and layout stability—not only clicks.
For a quick reapplication during a redesign, follow this sequence: choose the WPM policy, identify the article-content selector, add a semantic output element, calculate on the server or at build time when possible, test a short and long article, then verify keyboard, screen-reader, mobile, and translated views. Keep the label close to the headline and make its wording consistent across the site.
Finally, record the calculation rule in your content documentation. When another editor updates an article, they should be able to reproduce the estimate without guessing. That small piece of documentation turns a one-off reading time feature into a maintainable publishing tool.