如何在 Next.js 中为非默认语言环境生成动态路径?

How to generate dynamic paths for non-default locales in Next.js?

我正在使用 next-i18next 构建一个具有国际化功能的 Next.js 应用程序。为我网站的所有页面生成英语和法语页面,具有动态路由的页面除外:(即 blog/[id]/[blog-title])。对于具有动态路由的页面,页面是为英语生成的,而不是为法语生成的。

我应该注意到两种语言的博客条目是相同的。因此,如果用户单击列表中的博客条目,他们将获得相同的博客条目。

当法语用户使用动态路由访问页面时,他们会收到 404。我是 React 和 Next 的新手,所以我可能会在这里做一些愚蠢的事情。

// next-i18next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'fr'],
    defaultLocale: 'en',
    localeDetection: true,
  },
}
//
// blog\[id]\[title] 
//
export async function getStaticPaths() {
  const response = await axios.get('https://api.myappi.com/blog')
  const posts = response.data

  const paths = posts.map((post: Props) => ({
    params: { id: post.Id, title: post.Title },
  }))  
 
  return { paths, fallback: false }
}

export async function getStaticProps(props: IStaticProps) {
  const { id, locale } = props.params
  const response = await axios.get(`https://api.myappi.com/blog/${id}`)
  const post = await response.data

  if (!post) {
    return {
      notFound: true,
    }
  }

  return {
    props: { 
      Id: post.Id,
      Title: post.Title,
      Blog: post.Blog,
      DatePosted: post.DatePosted, 
      PostedBy: post.PostedBy,
      ...(await serverSideTranslations(props.locale, ['common', 'blog']))
    }
  }
}

对于动态路由,您必须明确 return 您希望从 getStaticPaths 函数中预先生成的语言环境。如果不这样做,Next.js 将只为默认语言环境生成页面。

来自 Internationalized Routing 文档:

For pages using getStaticProps with Dynamic Routes, all locale variants of the page desired to be prerendered need to be returned from getStaticPaths. Along with the params object returned for paths, you can also return a locale field specifying which locale you want to render.

这可以通过修改您的 getStaticPaths 函数来为每个 slug/locale 组合生成一个路径来实现。

export async function getStaticPaths({ locales }) { // Get available locales from `context`
   const response = await axios.get('https://api.myappi.com/blog')
   const posts = response.data

   const paths = posts
       .map((post: Props) => locales.map((locale) => ({
           params: { id: post.Id, title: post.Title },
           locale // Pass locale here
       })))
       .flat() // Flatten array to avoid nested arrays
 
   return { paths, fallback: false }
}