Перейти к содержимому

Add reading time

Это содержимое пока не доступно на вашем языке.

Create a mdast 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.

  1. Install the following packages depending on the Markdown processor used:

    Terminal window
    npm install reading-time @astrojs/markdown-satteri satteri
  2. Create a mdast plugin.

    This plugin retrieves the Markdown file’s text. This text is then passed to the reading-time package to calculate the reading time in minutes.

    src/mdast/mdast-reading-time.ts
    import getReadingTime from "reading-time";
    import { defineMdastPlugin } from "satteri";
    export const mdastReadingTimePlugin = defineMdastPlugin({
    name: "mdast-reading-time",
    after(root, context) {
    const textOnPage = context.textContent(root);
    const readingTime = getReadingTime(textOnPage);
    if (context.data.astro !== undefined) {
    // readingTime.text will give us minutes read as a friendly string,
    // i.e. "3 min read"
    context.data.astro.frontmatter.minutesRead = readingTime.text;
    }
    },
    });
  3. Add the plugin to your config:

    astro.config.mjs
    import { satteri } from "@astrojs/markdown-satteri";
    import { defineConfig } from "astro/config";
    import { mdastReadingTimePlugin } from "./src/mdast/mdast-reading-time";
    export default defineConfig({
    markdown: {
    processor: satteri({
    mdastPlugins: [mdastReadingTimePlugin],
    }),
    },
    });

    Now all Markdown documents will have a calculated minutesRead property in their frontmatter.

  4. Display Reading Time

    If your blog posts are stored in a content collection, access the remarkPluginFrontmatter from the render() function. Then, render minutesRead in your template wherever you would like it to appear.

    src/pages/posts/[slug].astro
    ---
    import { getCollection, render } from "astro:content";
    export async function getStaticPaths() {
    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>
    <meta charset="utf-8" />
    <title>{entry.data.title}</title>
    </head>
    <body>
    <title>{entry.data.title}</title>
    <p>{remarkPluginFrontmatter.minutesRead}</p>
    <Content />
    </body>
    </html>

    If you’re using a Markdown layout, use the minutesRead frontmatter property from Astro.props in your layout template.

    src/layouts/BlogLayout.astro
    ---
    const { minutesRead } = Astro.props.frontmatter;
    ---
    <html>
    <head>
    <meta charset="utf-8" />
    </head>
    <body>
    <p>{minutesRead}</p>
    <slot />
    </body>
    </html>
Внести свой вклад Сообщество Поддержать