如何为AstroPaper博客添加阅读时长(Read Time)功能
为 Astro Paper 添加阅读时长功能分步教程
1. 创建阅读时长计算工具函数
在项目的 src/utils 目录下新建 readTime.ts 文件(无utils目录则先创建),添加以下代码:
export function calculateReadTime(content: string): number { // 过滤Markdown/MDX语法,提取纯文本 const plainText = content .replace(/<[^>]*>/g, '') // 移除HTML标签 .replace(/\[.*?\]\(.*?\)/g, '') // 移除Markdown链接 .replace(/!\[.*?\]\(.*?\)/g, '') // 移除Markdown图片 .replace(/`.*?`/g, '') // 移除代码块 .replace(/\*\*.*?\*\*/g, '') // 移除粗体格式 .replace(/\*.*?\*/g, '') // 移除斜体格式 .replace(/#+/g, '') // 移除标题符号 .trim(); // 统计字数:中文按单个字符、英文按单词计数 const wordCount = plainText.match(/[\u4e00-\u9fa5]+|\w+/g)?.length || 0; const wordsPerMinute = 200; // 平均阅读速度,可按需调整 const readTime = Math.ceil(wordCount / wordsPerMinute); return readTime < 1 ? 1 : readTime; // 最低显示1分钟 }
2. 在文章集合中注入阅读时长字段
修改 src/content/config.ts 文件,为博客集合添加阅读时长的自动计算逻辑:
import { defineCollection, z } from 'astro:content'; import { calculateReadTime } from '../utils/readTime'; const blog = defineCollection({ schema: ({ image }) => z.object({ // 保留原有字段(title、pubDate、description等) title: z.string(), pubDate: z.date(), description: z.string(), // ...其他原有字段 // 定义阅读时长字段,默认值为0 readTime: z.number().default(0), }), // 处理文章时自动计算阅读时长 extend: async (entry) => { const { content } = await entry.render(); return { data: { readTime: calculateReadTime(content), }, }; }, }); export const collections = { blog };
3. 在文章列表卡片显示阅读时长
打开文章列表组件 src/components/BlogCard.astro,在元信息区域添加阅读时长:
--- import type { CollectionEntry } from 'astro:content'; export interface Props { post: CollectionEntry<'blog'>; } const { post } = Astro.props; --- <div class="blog-card"> <h3><a href={`/posts/${post.slug}`}>{post.data.title}</a></h3> <p class="post-meta"> {post.data.pubDate.toLocaleDateString()} <!-- 新增阅读时长显示 --> <span>• {post.data.readTime} min read</span> </p> <p>{post.data.description}</p> </div>
4. 在文章详情页显示阅读时长
打开文章详情页组件 src/pages/posts/[slug].astro,在头部元信息区添加阅读时长:
--- import type { CollectionEntry } from 'astro:content'; import { getCollection } from 'astro:content'; export async function getStaticPaths() { const posts = await getCollection('blog'); return posts.map((post) => ({ params: { slug: post.slug }, props: { post }, })); } interface Props { post: CollectionEntry<'blog'>; } const { post } = Astro.props; --- <article> <header> <h1>{post.data.title}</h1> <div class="post-meta"> <time datetime={post.data.pubDate.toISOString()}> {post.data.pubDate.toLocaleDateString()} </time> <!-- 新增阅读时长显示 --> <span>• {post.data.readTime} min read</span> </div> </header> <section>{post.content}</section> </article>
5. 样式优化(可选)
若需要调整阅读时长的显示样式,可在全局CSS文件(如 src/styles/global.css)中添加:
.post-meta span { color: #666; margin-left: 0.5rem; }
完成以上步骤后,重启开发服务器(npm run dev),即可在文章列表和详情页看到自动计算的阅读时长。
内容的提问来源于stack exchange,提问作者Drexster
相关产品推荐
相关产品推荐

