AstroJS如何向getStaticPaths()传递数据实现年月博客索引
Astro 动态路由中向 getStaticPaths 传递年份参数的解决方案
核心原理说明
getStaticPaths 是 Astro 在构建阶段预执行的函数,无法直接访问运行时的 Astro.params。要实现按年份过滤后生成月份路由,需从源数据层面提取所有有效 (year, month) 组合,直接生成对应路由,而非试图向 getStaticPaths 传递外部参数。
具体实现步骤
以 /blog/[year]/[month]/index.astro 页面为例:
获取全量博客数据
从本地 Markdown 文件、数据库或 API 拉取所有博客文章的元数据(包含日期、slug 等关键信息)。提取唯一的(year, month)组合
遍历全量文章,解析日期并生成唯一的年月键值对,避免重复生成路由。在 getStaticPaths 中生成路由
将年月组合转换为路由参数,同时可预过滤对应年月的文章并通过props传递给页面,减少运行时计算。页面组件中渲染对应内容
通过Astro.params获取年月参数,或直接使用props中预过滤的文章数据渲染列表。
代码示例
--- // 导入自定义的文章获取工具(根据你的实际实现调整) import { getAllPosts } from '../../utils/posts'; export async function getStaticPaths() { const allPosts = await getAllPosts(); // 提取所有唯一的(year, month)组合 const yearMonthSet = new Set(); allPosts.forEach(post => { const date = new Date(post.date); const year = date.getFullYear().toString(); // 统一月份为两位格式(如01、12),避免路由格式不一致 const month = String(date.getMonth() + 1).padStart(2, '0'); yearMonthSet.add(`${year}-${month}`); }); // 生成路由配置 return Array.from(yearMonthSet).map(pair => { const [year, month] = pair.split('-'); return { params: { year, month }, // 预过滤对应年月的文章,传递给页面组件 props: { filteredPosts: allPosts.filter(post => { const postDate = new Date(post.date); return postDate.getFullYear().toString() === year && String(postDate.getMonth() + 1).padStart(2, '0') === month; }) } }; }); } // 从路由参数或props中获取数据 const { year, month } = Astro.params; const { filteredPosts } = Astro.props; --- <!-- 页面渲染逻辑 --> <h1>{year}年{month}月博客列表</h1> <ul> {filteredPosts.map(post => ( <li> <a href={`/blog/${year}/${month}/${post.date.slice(8,10)}/${post.slug}`}> {post.title} </a> </li> ))} </ul>
关键注意点
- 月份格式需统一为两位数字,避免出现
/2024/1和/2024/01这类不一致的路由。 - 通过
props预过滤文章,可避免页面组件重复遍历全量数据,提升构建和运行效率。 - 该逻辑与你已实现的
/blog/[year]/index.astro路由逻辑同源,仅多了月份维度的筛选,保持代码一致性。
内容的提问来源于stack exchange,提问作者Wen Tai
相关产品推荐
相关产品推荐

