全栈开发个人博客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')}
    />
  )
}
相关推荐
Codebee2 小时前
打破偏见!企业级AI不是玩具!Ooder全栈框架+程序员=专业业务系统神器
前端·全栈
realze2 天前
关于我80%的代码都用AI生成这件事
人工智能·代码规范·全栈
ssshooter3 天前
彻底搞懂 SSH 与 Git 的“幕后交易”
git·github·全栈
ZsTs1193 天前
《2025 AI 自动化新高度:一套代码搞定 iOS、Android 双端,全平台 AutoGLM 部署实战》
前端·人工智能·全栈
jun_不见3 天前
nest初体验-用nest实现一个简单的CRUD功能
前端·node.js·全栈
前端双越老师3 天前
自由职业者 2025 年终总结:转型 AI 全栈
面试·ai编程·全栈
小皮虾4 天前
搞全栈还在纠结 POST、GET、RESTful?试试这个,像调用本地函数一样写接口
前端·node.js·全栈
小皮虾7 天前
别再封装 Axios 了!用 RPC 像调用本地函数一样写接口(支持 Vue/React/Node)
前端·rpc·全栈
Mintopia7 天前
🧭 Next.js 服务器部署摘要
react.js·全栈·next.js