全栈开发个人博客02:国际化

next-intl 是一个用于 Next.js 应用的国际化库,简化了多语言支持,通过 useTranslationsFormattedMessage 等组件来管理翻译内容,支持构建时静态渲染,服务端组件和客户端组件都可以使用。

1. 配置国际化

  • 安装依赖
bash 复制代码
pnpm add next-intl
  • 使用 App Router with routing 的国际化配置,根据官网配置完成后,文件结构如下:
bash 复制代码
├── messages
│   ├── en.json
│   └── ...
├── next.config.ts
└── src
    ├── i18n
    │   ├── routing.ts
    │   ├── navigation.ts
    │   └── request.ts
    ├── middleware.ts
    └── app
        └── [locale]
            ├── layout.tsx
            └── page.tsx

2. 支持静态渲染

  1. 在 layout.tsx 中添加 generateStaticParams 方法,为所有路由开启静态渲染
tsx 复制代码
// src/app/[locale]/layout.tsx
import { routing } from '@/i18n/routing'
export function generateStaticParams() {
  return routing.locales.map((locale) => ({ locale }))
}
  1. 在 所有 layout.tsx 和 page.tsx 中使用 setRequestLocale 设置请求的国际化语言
tsx 复制代码
// src/app/[locale]/layout.tsx
import { setRequestLocale } from 'next-intl'

setRequestLocale(locale)
tsx 复制代码
// src/app/[locale]/page.tsx
import { setRequestLocale } from 'next-intl'

setRequestLocale(locale)

3. 根域名需要重定向到默认语言

tsx 复制代码
// src/app/page.tsx
import { redirect } from 'next/navigation'

export default function RootPage() {
  redirect('/en')
}

4. 切换域名使用i18n自带的router.replace(),保留当前用户访问路径

tsx 复制代码
// LocaleSwitcherSelect.tsx

'use client'
import { useParams } from 'next/navigation'
import { usePathname, useRouter } from '@/i18n/navigation'
import { Locale, routing } from '@/i18n/routing'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { Languages } from 'lucide-react'
import { useLocale, useTranslations } from 'next-intl'
import { useTransition } from 'react'
type Props = {
  defaultValue: string
  items: Array<{ value: string; label: string }>
  label: string
}

function LocaleSwitcherSelect({ defaultValue, items, label }: Props) {
  const [isPending, startTransition] = useTransition()
  const router = useRouter()
  const pathname = usePathname()
  const params = useParams()

  function onChange(value: string) {
    const nextLocale = value as Locale
    startTransition(() => {
      router.replace({ pathname, params }, { locale: nextLocale })
    })
  }

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <div className="hover:bg-accent hover:text-accent-foreground cursor-pointer p-2 transition-colors">
          <Languages className="size-4" />
        </div>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        {items.map((item) => (
          <DropdownMenuItem
            key={item.value}
            onClick={() => onChange(item.value)}
          >
            {item.label}
          </DropdownMenuItem>
        ))}
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

export default function LocaleSwitcher() {
  const t = useTranslations('LocaleSwitcher')
  const locale = useLocale()

  return (
    <LocaleSwitcherSelect
      defaultValue={locale}
      items={routing.locales.map((locale) => ({
        value: locale,
        label: t(locale),
      }))}
      label={t('label')}
    />
  )
}
相关推荐
我就是马云飞3 天前
大专毕业两年,我如何进入大厂,并逆袭八年的技术与认知成长
前端·程序员·全栈
前端双越老师3 天前
为什么说 OpenClaw 应该装在自己的电脑上
人工智能·agent·全栈
程序员飞哥3 天前
到底Java 适不适合做 AI 呢?
后端·程序员·全栈
得物技术4 天前
基于 Cursor Agent 的流水线 AI CR 实践|得物技术
前端·程序员·全栈
问道飞鱼8 天前
【技术方案】面向 Web 系统的《全栈灰度部署方案设计》
前端·全栈·灰度发布
前端缘梦8 天前
Next.js 实现AI流式输出(打字机效果)
前端·面试·全栈
前端双越老师9 天前
OpenClaw小龙虾新手使用记录
agent·全栈
DanCheOo9 天前
流式输出:让 AI 回复像 ChatGPT 一样打字机效果
前端·全栈
DanCheOo9 天前
我写了一个 AI Commit Message 生成器,再也不用想怎么写 git commit 了
git·全栈