Nextra i18n

警告

Next.js I18n 仅支持 nextra-theme-docs (奇怪,blog模式不支持?)

Nextra默认就支持 Next.js Internationalized Routing ,所以只需要就配置可以支持国际化。

  • 修改 next.config.mjs :

next.config.mjs 配置 i18n
import nextra from 'nextra'

// Set up Nextra with its configuration
const withNextra = nextra({
  // ... Add Nextra-specific options here
})

// Export the final Next.js config with Nextra included
export default withNextra({
  // ... Add regular Next.js options here
  i18n: {
    locales: ['en', 'zh'],
    defaultLocale: 'en'
  }
})
  • 配置文档theme: 在 theme.config.jsx 中添加 i18n 选项以配置语言下拉列表:

配置语言下拉列表 theme.config.jsx
import React from 'react'
import { DocsThemeConfig } from 'nextra-theme-docs'

const config: DocsThemeConfig = {
  logo: <span>Cloud Atlas: Architecture</span>,
  project: {
    link: 'https://github.com/huataihuang/cloud-atlas.dev_arch',
  },
  chat: {
    link: 'https://discord.com',
  },
  docsRepositoryBase: 'https://github.com/huataihuang/cloud-atlas.dev_arch',
  footer: {
    text: 'Cloud Atlas by Huatai Huang',
  },
}

i18n: [
  { locale: 'en', name: 'English' },
  { locale: 'zh', name: '中文' }
]

我这里遇到一个报错问题,显示 TypeError :

TypeError
✓ Compiled /[lang]/[[...mdxPath]] in 158.9s
 ⨯ TypeError: {(intermediate value)(intermediate value)}[lang] is not a function
    at RootLayout (app/[lang]/layout.jsx:42:34)
  40 |           banner={banner}
  41 |           navbar={navbar}
> 42 |           pageMap={await getPageMap()}
     |                                  ^
  43 |           docsRepositoryBase="https://github.com/huataihuang/docs.cloud-atlas.dev/tree/main/docs"
  44 |           footer={footer}
  45 |           // ... Your additional layout options {
  digest: '3788460784'
}
 ⨯ TypeError: {(intermediate value)(intermediate value)}[lang] is not a function
    at Page (app/[lang]/[[...mdxPath]]/page.jsx:16:34)
  14 | export default async function Page(props) {
  15 |   const params = await props.params
> 16 |   const result = await importPage(params.mdxPath)
     |                                  ^
  17 |   const { default: MDXContent, toc, metadata } = result
  18 |   return (
  19 |     <Wrapper toc={toc} metadata={metadata}> {
  digest: '76952206'
}
 GET /about 500 in 178198ms
  • 参考 next.js App Router > Guides > Internationalization 国际化是 Routing 是通过子目录( 例如 /fr/products )或 域名( my-site.fr/products )来实现。所以,该指南指出要确保所有位于 app/ 目录下特定文件要 nested 进入 app/[lang] ,这样Next.js就能够动态处理的不同locales的路由

我参考了 nextra/examples/swr-site/ 案例,尝试将 app/ 目录下的 layout.jsx[[...mdxPath]] 目录移动到 [lang] 自目录下,但是报错依旧 如上

原来在 next.js App Router > Guides > Internationalization 提到针对 app/[lang] 是转发给每个 layoutpagelang 参数,例如 app/[lang]/page.tsx :

app/[lang]/page.tsx
// You now have access to the current locale
// e.g. /en-US/products -> `lang` is "en-US"
export default async function Page({
  params,
}: {
  params: Promise<{ lang: string }>
}) {
  const { lang } = await params
  return ...
}

我对比了 nextra/examples/swr-site/ 确实和原先从 GitHub: shuding/nextra-docs-template 复制过来的模版不同,提供了关于 lang 参数的路由:

包含 lang 参数的 layout.tsx
type LayoutProps = Readonly<{
  children: ReactNode
  params: Promise<{
    lang: string
  }>
}>

const RootLayout: FC<LayoutProps> = async ({ children, params }) => {
  const { lang } = await params
  const dictionary = await getDictionary(lang)
  let pageMap = await getPageMap(`/${lang}`)

  if (lang === 'en') {
    pageMap = [
      ...pageMap,
      {
        name: 'remote',
        route: '/remote',
        children: [graphqlYogaPageMap],
        title: 'Remote'
      },
      graphqlEslintPageMap
    ]
  }
  ...

我的解决方法

我重做了 Nextra快速起步 的模版复制步骤,也就是

参考