使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
此页面的内容已使用 AI 翻译。
查看英文原文的最新版本If you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
New Intlayer v9 - What's new?
Welcome to Intlayer v9! This major release marks a huge milestone in simplifying the migration path to Intlayer with Compat Adapter Packages for major i18n libraries (react-i18next, next-intl, vue-i18n, etc.) and adds support for rich content structures: Collections and Variants.
Table of contents
Compat Adapter Packages
Migrating to Intlayer from popular i18n libraries is now easier than ever. We have created five compat packages that expose the exact same public APIs as standard i18n libraries but delegate all translation work to Intlayer at runtime.
Expose Same Public API with Strict Typing
By replacing imports, you get all the benefits of Intlayer (including compile-time type safety against your actual dictionaries) with minimal code changes:
@intlayer/i18next@intlayer/react-i18next@intlayer/next-intl@intlayer/react-intl@intlayer/next-i18next@intlayer/vue-i18n@intlayer/lingui
For example, simply change:
复制代码到剪贴板
import { useTranslation } from "react-i18next";to:
复制代码到剪贴板
import { useTranslation } from "@intlayer/react-i18next";Your keys will now be strictly typed against your Intlayer dictionaries, offering full dot-path auto-completion in your IDE!
Bundler Alias Plugins (Vite, Next.js, Turbopack)
To allow migrating without rewriting all your import statements manually, each compat adapter package includes a custom bundler plugin (Vite or Next.js) under the /plugin subpath.
These plugins automatically rewrite existing imports (e.g. react-i18next or next-intl) to their @intlayer/* equivalents at build time.
Next.js (Webpack / Turbopack) Example
Instead of withIntlayer, wrap your Next.js configuration with the compat plugin:
复制代码到剪贴板
import { createNextI18nPlugin } from "@intlayer/next-i18next/plugin";import type { NextConfig } from "next";const withIntlayer = createNextI18nPlugin();const nextConfig: NextConfig = {};export default withIntlayer(nextConfig);Vite (React, Vue, Solid, Svelte) Example
复制代码到剪贴板
import vueI18nVitePlugin from "@intlayer/vue-i18n/plugin";export default defineConfig({ plugins: [vueI18nVitePlugin()],});Mutualized Runtime Resolver
All compat adapters now route translation resolution through a single, highly optimized runtime parser: @intlayer/core/messageFormat.
- Interpolate Message: Resolves standard
{{var}}(whitespace & dot-paths), ICU formatted args ({v, number, percent}etc.), and bare{var}templates. - Message Node Resolver: Resolves nested nodes:
insert(),plural()(CLDR plural rules),enu()(enumeration),gender(), HTML tags, arrays, and callable function nodes. - Tokenized Tag Parser: Supports inline XML/HTML tags and numbered tags (e.g.,
<1>children</1>) to power rich-text rendering out of the box.
Feature Spec: Collections & Variants
Intlayer v9 expands beyond static key-value objects, allowing dictionaries to declare dynamic layout structures that are fully typed end-to-end.
1. Collections
Define a CMS-managed list of ordered items (e.g. FAQs, products, or blog lists):
复制代码到剪贴板
import { t, type Dictionary } from "intlayer";export default { key: "faq", item: 1, content: { question: t({ en: "What is Intlayer?", fr: "Qu'est-ce qu'Intlayer ?" }), answer: t({ en: "An i18n toolkit.", fr: "Une boîte à outils i18n." }), },} satisfies Dictionary;复制代码到剪贴板
import { t, type Dictionary } from "intlayer";export default { key: "faq", item: 2, content: { question: t({ en: "Is it free?", fr: "Est-ce gratuit ?" }), answer: t({ en: "Yes, open-source.", fr: "Oui, open-source." }), },} satisfies Dictionary;Usage:
复制代码到剪贴板
// Fetch all items as an arrayconst allFaqs = useIntlayer("faq"); // -> { question: string, answer: string }[]// Fetch a single item by indexconst faq = useIntlayer("faq", { item: 2 }); // -> { question: string, answer: string }2. Variants
Deliver A/B tests, seasonal headers, feature flags, or custom landing pages:
String variants (e.g. A/B testing)
复制代码到剪贴板
import { t, type Dictionary } from "intlayer";export default { key: "hero-banner", variant: "default", content: { control: t({ en: "Welcome", fr: "Bienvenue" }), black_friday: t({ en: "Shop now", fr: "Acheter maintenant" }), },} satisfies Dictionary;Usage:
复制代码到剪贴板
const banner = useIntlayer("hero-banner", { variant: "black_friday" });Object variants (e.g. Dynamic Records)
复制代码到剪贴板
import { t, type Dictionary } from "intlayer";export default { key: "product-copy", variant: { id: "prod_123", category: "books", }, content: { title: t({ en: "Clean Code", fr: "Code Propre" }), },} satisfies Dictionary;Usage:
复制代码到剪贴板
// Fetches only the requested item dynamically (requires Suspense)const product = useIntlayer("product-copy", { variant: { id: "prod_123", category: "books" },});Vite Plugin: 捆绑编译器和代理
intlayer() Vite 插件现在直接捆绑了编译器和区域设置路由代理,因此大多数项目只需在 vite.config.ts 中使用单个插件:
复制代码到剪贴板
import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";export default defineConfig({ plugins: [intlayer()],});- Compiler: 当
compiler.enabled被设置为true且配置了compiler.output路径时,自动激活。您不再需要单独注册intlayerCompiler()。 - Proxy: 根据新的
routing.enableProxy选项自动激活(默认为true)。它在开发、预览和生产 SSR 中连接区域设置检测 / 重定向 / 重写中间件。您不再需要单独注册intlayerProxy()。
routing.enableProxy 选项
新的 routing.enableProxy 选项控制是否启用区域语言路由代理。默认值为 true。当您想自己处理区域语言路由时,可以禁用它:
复制代码到剪贴板
import type { IntlayerConfig } from "intlayer";const config: IntlayerConfig = { routing: { enableProxy: false, // 默认值: true },};export default config;独立的 intlayerCompiler() 和 intlayerProxy() 插件仍然可用于高级设置。将它们与 intlayer() 一起注册是安全的 — 每个插件会自动去重并且仅运行一次。
默认禁用编译器
从 Intlayer v9 开始,编译器默认被禁用(compiler.enabled 现在默认为 false)。要启用对 .content.ts 文件的构建时提取,请在配置中设置 compiler.enabled: true:
复制代码到剪贴板
import type { IntlayerConfig } from "intlayer";const config: IntlayerConfig = { compiler: { enabled: true, // 默认值:false —— 自 v9 起启用编译器所必需 output: ({ fileName }) => `./${fileName}.content.ts`, },};export default config;当编译器被禁用时,Intlayer 会跳过构建时提取步骤,并依赖您已声明的字典。仅当您希望打包器插件(@intlayer/swc、@intlayer/babel 或 intlayer() Vite 插件)自动提取内容时才启用它。
React Native:单包导入
在 React Native 或 Expo 应用中,您不再需要同时管理 react-intlayer 和 react-native-intlayer。react-native-intlayer 包现在重新导出了完整的 react-intlayer API(hooks、工具函数以及 /format、/html 和 /markdown 子路径),并且其 IntlayerProvider 会自动应用 React Native 的 polyfills。
从单一的 react-native-intlayer 包中导入所有内容:
复制代码到剪贴板
import { IntlayerProvider, useIntlayer, useLocale,} from "react-native-intlayer";复制代码到剪贴板
npm install intlayer react-native-intlayer从react-intlayer导入仍然有效,但现在推荐使用react-native-intlayer作为 React Native 的单一入口点 —— 它的 provider 提供了面向 web 的react-intlayerprovider 所不包含的 polyfills。
CMS SDK:将 Intlayer 用作无头内容数据库
Intlayer v9 在 @intlayer/api 中提供了一个简洁、自动鉴权的 SDK,用于以编程方式与 CMS 交互——获取项目、获取字典,以及从你自己的服务器、脚本或 CI 推送或更新它们。鉴权(OAuth2 client_credentials)会自动处理并刷新。
SDK 拆分为两个独立的导入,因此你的打包产物只包含你实际使用的领域:
createIntlayerCMS—— 一个轻量的鉴权器,持有凭据和受管理的令牌(不打包任何领域客户端)。dictionaryEndpoint、projectEndpoint、… —— 按领域划分的端点绑定器,各自从其独立子路径导入。
复制代码到剪贴板
import { createIntlayerCMS } from "@intlayer/api";import { dictionaryEndpoint } from "@intlayer/api/dictionary";// 配置是可选的:凭据会回退到 INTLAYER_CLIENT_ID /// INTLAYER_CLIENT_SECRET(由 `@intlayer/config/built` 解析)。const cms = createIntlayerCMS();// 读取const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();// 写入 —— 像数据库一样使用 CMSawait dictionaryEndpoint(cms).pushDictionaries([myDictionary]);安全:CMS 凭据授予对内容的写入权限。务必只在服务端创建鉴权器——切勿将clientId/clientSecret发送到浏览器。
Migration notes from v8
If you are upgrading from v8, note that the v9 does not include breaking changes. But here are the key changes:
- 默认禁用编译器:
compiler.enabled现在默认为false。如果您依赖对.content.ts文件的构建时提取,请在intlayer.config.ts中设置compiler.enabled: true。 - Locales & Dialects: If using external i18n dependencies, add their respective compat adapter plugins in your configuration or bundler setup to automatically rewrite imports.
- Custom Selectors: When calling
useIntlayer, the second parameter is now reserved for an option object containing{ locale, item, variant }. If you previously passed a locale string directly, you can still do so, but using the options object is recommended for advanced selections.