November 29, 2023

Add Reading Time Estimates to Your Next.js Blog

I always like seeing reading time estimates for blog articles before I click the link. I wanted to add this feature to my personal blog built with Next.js, too.

Here's how I did it:

1. reading-duration

I found an npm package named reading-duration that does a great job of calculating this value based on words per minute while ignoring HTML tags. This is especially helpful when working with MDX files.

Add it to your Next.js project with:

npm i reading-duration

2. Understand the settings

You pass in your content to the readingDuration function this package provides, but there are some optional settings, too. You can set the wordsPerMinute (defaults to 200), and if you want, you can set the returned value to include an emoji (which is an hourglass ⏳).

import readingDuration from 'reading-duration'

const readingTime = readingDuration(rawMDXContent, {
  wordsPerMinute: 100 
  emoji: false
})

3. Add reading-duration to Your Next.js Blog

I store my MDX blog article files on GitHub and fetch them as my Next.js blog builds static pages. Below is an abbreviated version of what is happening in my code:

export async function getPostByName(fileName: string) {
    const res = await fetch(`my-github-url/${fileName}`)

    const rawMDX = await res.text()

    const duration = readingDuration(rawMDX, {
        emoji: false,
    })
}

I save the above duration value with the other front matter for the blog post. You can see I went with the default wordsPerMinute and declined the default emoji. When I use the duration value, I use an open book πŸ“– emoji instead.

4. Update!

I thought it would be a nice addition to the reading-duration package if we could have more emoji options built-in. I submitted a pull request on GitHub with my suggested update. I just received a reply from the author, and it looks like the update will be merged.

With the update you can provide a boolean | string data type for the emoji option value. The boolean values work as shown above. The new string values provide different emojis in the output string.

Here's a quick look at all possible emoji option values after the update:

  • true: 'βŒ› '
  • false: no emoji
  • hourglass_done: 'βŒ› '
  • hourglass_not_done: '⏳ '
  • stopwatch: '⏱ '
  • clock: 'πŸ•’ '
  • watch: '⌚ '
  • timer: '⏲ '
  • alarm: '⏰ '
  • books: 'πŸ“š '
  • open_book: 'πŸ“– '
  • closed_book: 'πŸ“• '
  • blue_book: 'πŸ“˜ '
  • green_book: 'πŸ“— '
  • orange_book: 'πŸ“™ '
  • notebook: 'πŸ““ '
  • notebook_alt: 'πŸ“” '