如何用Astro JS+Decap CMS+astro-i18next实现多语言博客路由?
解决Astro + Decap CMS + astro-i18next多语言博客路由问题
1. 调整Decap CMS配置,支持独立多语言slug
修改admin/config.yml里的博客集合配置,让编辑器能为每种语言设置专属slug,同时调整文件存储结构为后缀式:
collections: - name: 'blog' label: 'Blog' folder: 'content/blog' create: true fields: - { label: '标题', name: 'title', widget: 'string', i18n: true } - { label: '自定义路径', name: 'slug', widget: 'string', i18n: true } - { label: '正文', name: 'body', widget: 'markdown', i18n: true } i18n: structure: 'suffix' locales: ['en', 'es'] default_locale: 'en'
配置后,Decap CMS会生成first-post.en.md、primera-entrada.es.md这类文件(不再用语言子文件夹),且允许西班牙语文章设置独立的slug。
2. 配置Astro内容集合适配多语言
在src/content/config.ts里定义博客集合,明确多语言规则:
import { defineCollection, z } from 'astro:content'; const blogCollection = defineCollection({ schema: z.object({ title: z.string(), slug: z.string(), }), locales: ['en', 'es'], defaultLocale: 'en', }); export const collections = { 'blog': blogCollection, };
这样Astro就能从文件名的后缀识别语言,正确读取不同语言的文章数据。
3. 用动态路由生成正确URL
创建src/pages/blog/[...slug].astro动态路由文件,处理多语言路由逻辑:
--- import { getCollection } from 'astro:content'; import { i18n } from 'astro-i18next'; export async function getStaticPaths() { const allPosts = await getCollection('blog'); return allPosts.map(post => { // 根据语言生成对应路径:默认语言直接用/blog/{slug},其他语言前缀加/{locale} const path = post.locale === i18n.defaultLocale ? `/blog/${post.data.slug}` : `/${post.locale}/blog/${post.data.slug}`; return { params: { slug: post.data.slug }, props: { post }, locale: post.locale, }; }); } const { post } = Astro.props; --- <main> <h1>{post.data.title}</h1> <article>{await post.render()}</article> </main>
这会自动生成符合要求的路由:
- 英文文章:
website.com/blog/first-post - 西班牙文文章:
website.com/es/blog/primera-entrada
4. 迁移旧文章(可选)
如果之前已经有存在语言子文件夹的文章,手动迁移到content/blog根目录,并重命名为{slug}.{locale}.md格式,比如把content/blog/es/first-post.md改成content/blog/primera-entrada.es.md。
5. 验证效果
启动Astro开发服务器后,检查:
- 英文博客能否通过
/blog/{slug}正常访问 - 西班牙文博客能否通过
/es/blog/{slug}正常访问 - 语言切换功能是否能正确跳转对应语言的文章页面
内容的提问来源于stack exchange,提问作者quasi
相关产品推荐
相关产品推荐

