Add reading time
Create a remark plugin which adds a reading time property to the frontmatter of your Markdown or MDX files. Use this property to display the reading time for each page.
Recipe
Section titled “Recipe”-
Install the following packages:
reading-timeto calculate minutes readmdast-util-to-stringto extract all text from your markdown@astrojs/markdown-remarkto use theunified()processor:
-
Create a remark plugin.
This plugin uses the
mdast-util-to-stringpackage to get the Markdown file’s text. This text is then passed to thereading-timepackage to calculate the reading time in minutes.remark-reading-time.mjs import getReadingTime from'reading-time';import { toString } from'mdast-util-to-string';exportfunctionremarkReadingTime() {returnfunction(tree, { data }) {const textOnPage = toString(tree);const readingTime = getReadingTime(textOnPage);// readingTime.text will give us minutes read as a friendly string,// i.e. "3 min read"data.astro.frontmatter.minutesRead=readingTime.text;};} -
Add the plugin to your config:
astro.config.mjs import { unified } from'@astrojs/markdown-remark';import { defineConfig } from'astro/config';import { remarkReadingTime } from'./remark-reading-time.mjs';exportdefaultdefineConfig({markdown: {processor: unified({remarkPlugins: [remarkReadingTime],}),},});Now all Markdown documents will have a calculated
minutesReadproperty in their frontmatter. -
Display Reading Time
If your blog posts are stored in a content collection, access the
remarkPluginFrontmatterfrom therender(entry)function. Then, renderminutesReadin your template wherever you would like it to appear.src/pages/posts/[slug].astro ---import { getCollection, render } from'astro:content';exportasyncfunctiongetStaticPaths() {const blog = await getCollection('blog');return blog.map(entry=> ({params: { slug: entry.id },props: { entry },}));}const { entry } = Astro.props;const { Content, remarkPluginFrontmatter } = await render(entry);---<html><head>...</head><body>...<p>{remarkPluginFrontmatter.minutesRead}</p>...</body></html>If you’re using a Markdown layout, use the
minutesReadfrontmatter property fromAstro.propsin your layout template.src/layouts/BlogLayout.astro ---const { minutesRead } = Astro.props.frontmatter;---<html><head>...</head><body><p>{minutesRead}</p><slot /></body></html>
