simpixelated.com

illustration of Jordan Kohl

Adding dynamic read time to Eleventy.js

- JavaScript, Eleventy, development — 2 min read

Prior to converting my blog to Eleventy.js, I was using the awesome Gatsby Starter: Minimal Blog theme by LekoArts, which dynamically calculated the reading time for each post. This is a fairly common feature that you see on many websites (and you can still see at the top of this page), which I think was popularized by Medium. When I converted this blog from Gatsby, I had to recreate the functionality in Eleventy.

Conceptually, this is how to calculate read time:

Simple! To add this to Eleventy, you have to wrap the logic in a filter that you can add to your Eleventy config. Since you'll be passing the entire content of your post to the filter, you'll need to strip out the HTML content first. Once you have the plain text, you can split it into words and calculate the read time by dividing by an average words per minute. It should look something like this:

eleventyConfig.addFilter("timeToRead", (content) => {
  const getPlainText = content => {
    const html = content.templateContent || content
    if (typeof html !== "string") {
      throw new Error("Time-to-read's input must be a string or template")
    }

    const htmlTags = String.raw`<\/?[a-z0-9]+\b[^>]*>`
    // regex = '<!--' + the minimal amount of 0 or more characters + '-->'
    const htmlComments = String.raw`<!--[^]*?-->`
    // remove any tags or comments
    return html.replace(
      new RegExp(String.raw`${htmlTags}|${htmlComments}`, "gi"),
      ""
    )
  }
  const rawText = getPlainText(content)
  const wpm = 265
  const words = rawText.trim().split(/\s+/).length
  const time = Math.ceil(words / wpm)
  return time
}

You can use it a Nunjucks template like this:

{{ content | timeToRead }} min read

I chose 265 words per minute based on Medium's WPM. If you want to add a lot more customization, including internationalization, checkout this Eleventy plugin by JKC-Codes. I "borrowed" a lot of the code above from their GitHub repo as well as this tutorial by Michael Burrows.

Message me on Twitter if you have any questions about customizing Eleventy.js or just want to show off what you've built!