全栈开发个人博客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')}
    />
  )
}
相关推荐
一只叫煤球的猫8 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈
小Lu的开源日常18 小时前
是时候开始 Build in Public「公开构建」了
产品·全栈·运营
前端双越老师11 天前
一个自由职业者的 2025 年中总结:主业+探索
前端·ai编程·全栈
用户05956611920912 天前
现代化 Java 企业级应用分层开发架构设计最佳实践
java·架构·全栈
草梅友仁12 天前
Better Auth 集成简化用户系统开发 | 2025 年第 25 周草梅周报
开源·github·全栈
idaibin13 天前
rustzen-admin 全栈管理后台起始模板
全栈
非优秀程序员14 天前
作为开发者,我最喜欢的 Github 开源工具(2025 年上半年榜单)
人工智能·开源·全栈
JVM高并发14 天前
Nginx使用 Lua 脚本调用外部 API 验证 Token
nginx·全栈
susnm14 天前
Dioxus 互动性
rust·全栈
保持学习ing15 天前
SpringBoot电脑商城项目--新增收获地址
java·spring boot·后端·jquery·全栈