You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Next.js的getStaticPaths&getStaticProps实现Strapi多语言博客

Next.js + Strapi 本地化详情页404问题修复

问题背景

当前使用Next.js和Strapi实现内容本地化,文件结构如下:

pages/ 
   blog/ 
    - [post].tsx
    - portfolio.tsx
  • portfolio.tsx可根据当前locale正确获取对应语言的文章,卡片显示正常,但点击卡片进入[post].tsx详情页时,无论当前域名(波兰语对应localhost:3000,英语对应example.com:3000),均出现404错误。
  • Strapi中同一篇文章的不同语言版本拥有独立ID(如波兰语版本ID为10,英语版本ID为12)。
  • 卡片跳转链接为:<Link href="/blog/${id}" locale={route.locale} />

现有代码的核心问题

1. getStaticPaths生成了无效路径

原代码中getStaticPaths仅请求单个locale的文章数据,然后为所有locale复用这些ID生成路径:

  • 仅获取波兰语文章的ID(10、11),然后为英语locale生成/en/blog/10、/en/blog/11等路径,但这些ID在英语版本中不存在,访问时触发404。
  • 英语文章的真实ID(12、13)未被纳入paths,因此访问/en/blog/12时,因fallback为false直接返回404。

2. getStaticProps缺少错误处理

原代码未处理API请求失败的情况,若请求到不存在的ID,会导致页面崩溃而非正确返回404。

修复方案

步骤1:修正getStaticPaths,生成全语言有效路径

遍历所有locale,分别获取每个语言下的文章ID,为每个locale生成对应的有效路径,确保每个路径的locale与文章ID匹配。

步骤2:优化getStaticProps,合并请求并添加错误处理

合并重复的API请求,同时增加请求失败时的404返回逻辑,避免页面崩溃。

完整修复代码

[post].tsx 修正后代码

export const getStaticPaths = async ({ locales }) => {
  // 遍历所有locale,获取对应语言的文章数据
  const articlesByLocale = await Promise.all(
    locales.map(async (locale) => {
      const res = await fetch(
        `https://strapi.com/api/articles?locale=${locale}&populate=*`
      );
      const data = await res.json();
      return { locale, articles: data.data };
    })
  );

  // 生成每个locale对应的有效路径
  const paths = articlesByLocale.flatMap(({ locale, articles }) =>
    articles.map((post) => ({
      params: { post: post.id.toString() },
      locale,
    }))
  );

  return {
    paths,
    fallback: false,
  };
};

export const getStaticProps = async (context) => {
  const id = context.params.post;

  // 合并请求,一次性获取文章及blocks数据
  const res = await fetch(
    `https://strapi.tincors.com/api/articles/${id}?populate[blocks][populate]=*`
  );

  // 处理请求失败或文章不存在的情况
  if (!res.ok) {
    return { notFound: true };
  }

  const data = await res.json();
  // 增加可选链避免空值报错
  const block_data_slider = data.data.attributes.blocks[0]?.files?.data || [];

  return {
    props: {
      article: data.data,
      slider: block_data_slider,
    },
  };
};

额外优化建议

如果希望用户通过统一的标识符(如slug)访问不同语言的文章(而非语言相关的ID),可以在Strapi中为文章添加全局唯一的slug字段(或本地化slug),然后:

  1. 将路由改为[slug].tsx
  2. 在getStaticPaths中基于slug生成路径
  3. 在getStaticProps中通过locale和slug参数请求对应语言的文章:
// getStaticProps示例
const res = await fetch(
  `https://strapi.tincors.com/api/articles?filters[slug][$eq]=${slug}&locale=${context.locale}&populate[blocks][populate]=*`
);

内容的提问来源于stack exchange,提问作者Evoworx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:25:25