Documentation
定制化

自定义多语言

配置应用的国际化内容和多语言支持

国际化系统概述

VibeAny 使用 Intlayer 作为国际化解决方案,对比Next.js的next-intl,Intlayer 最大的特点是完全类型安全,会让你获得极好的开发体验。

建议安装 Intlayer VSCode Extension 来获得更好的开发体验。

  • 完全类型安全,即可捕获翻译 key 错误。
  • 即时导航 – 单击useIntlayer键时快速跳转到正确的内容文件。
  • 轻松访问 Intlayer 命令 – 轻松构建、推、拉、填充、测试内容字典。
  • 测试词典 – 测试词典是否有缺失的翻译。
  • Intlayer 选项卡(活动栏) - 从带有工具栏和上下文操作(构建、拉取、推送、填充、刷新、测试、创建文件)的专用侧选项卡浏览和搜索词典。

多语言配置

多语言配置文件位于 intlayer.config.ts 文件中,请根据需要修改配置,这是完全类型安全的,你可以看到所有支持的语言和默认语言。

intlayer.config.ts

import { type IntlayerConfig, Locales } from "intlayer"

const config: IntlayerConfig = {
  internationalization: {
    locales: [Locales.ENGLISH, Locales.CHINESE], // 支持的语言
    defaultLocale: Locales.ENGLISH, // 默认语言
  },
}

内容配置文件

所有多语言内容配置文件位于 src/config/locale/ 目录下:

文件用途
landing.content.ts落地页内容
pricing.content.ts定价页内容
auth.content.ts登录/注册页内容
admin.content.ts管理后台内容
user-dashboard.content.ts用户仪表盘内容
404.content.ts404 页面内容
error.content.ts错误页面内容
config.content.ts配置页面内容
credit-packages.content.ts积分包内容
waitlist.content.ts等待列表页内容

定义多语言内容

使用 t() 函数定义多语言文本:

src/config/locale/landing.content.ts
import { type Dictionary, t } from "intlayer"

export default {
  key: "landing",
  content: {
    hero: {
      title: t({
        en: "Vibe Any AI Startups in hours, not days",
        zh: "VibeAny AI 加速想法落地",
      }),
      description: t({
        en: "VibeAny is a TanStack boilerplate for building AI SaaS startups.",
        zh: "VibeAny 是一个 TanStack Start 模板,用于构建 AI SaaS 创业项目。",
      }),
    },
  },
} satisfies Dictionary

提示

以下内容为技术细节,如果你无需修改过多代码,可以直接跳过。

在组件中使用

使用 useIntlayer hook 获取国际化内容:

import { useIntlayer } from "react-intlayer"

function HeroSection() {
  const { hero } = useIntlayer("landing")

  return (
    <div>
      <h1>{hero.title.value}</h1>
      <p>{hero.description.value}</p>
    </div>
  )
}

重要

务必使用 .value 属性获取文本内容,否则会渲染对象而非字符串。

添加新语言

  1. 在内容文件中添加新语言的翻译:
title: t({
  en: "Hello",
  zh: "你好",
  ja: "こんにちは", // 添加日语
}),
  1. intlayer.config.ts 文件中添加新语言:

路由国际化

VibeAny 使用 LocalizedLink 组件处理国际化路由:

import { LocalizedLink } from "@/shared/components/locale/localized-link"

// 自动根据当前语言添加路由前缀
<LocalizedLink to="/docs">文档</LocalizedLink>

函数式导航使用 useLocalizedNavigate

import { useLocalizedNavigate } from "@/shared/hooks/use-localized-navigate"

function MyComponent() {
  const navigate = useLocalizedNavigate()

  const handleClick = () => {
    navigate("/dashboard")
  }
}

禁止

不要直接使用 TanStack Router 的 Link 组件,它无法正确处理国际化路由前缀。

日期和数字格式化

对于日期和数字的本地化格式,可以使用浏览器原生 API:

const date = new Date()
const formattedDate = date.toLocaleDateString(locale, {
  year: "numeric",
  month: "long",
  day: "numeric",
})

const number = 1234567.89
const formattedNumber = number.toLocaleString(locale)

目录