使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
版本历史
- "添加对 YAML 和 Markdown 文件格式的支持"v8.10.02026/5/19
- "添加 `plural` 内容节点类型"v8.9.02026/5/12
- "添加 `html` 内容节点类型"v8.0.02026/1/28
- "Rename `live` import mode to `fetch` to better describe the underlying mechanism."v8.0.02026/1/24
- "添加字典选项 `location` 和 `schema`"v8.0.02026/1/18
- "添加对 JSON5 和 JSONC 文件格式的支持"v7.5.132026/1/10
- "添加 ICU 和 i18next 格式支持"v7.5.02025/12/13
- "添加字段文档"v6.0.02025/9/20
- "初始化历史"v5.5.102025/6/29
此页面的内容已使用 AI 翻译。
查看英文原文的最新版本如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。
文档的 GitHub 链接复制文档 Markdown 到剪贴板
内容文件
什么是内容文件?
Intlayer 中的内容文件是包含字典定义的文件。 这些文件声明了您的应用程序的文本内容、翻译和资源。 内容文件由 Intlayer 处理以生成字典。
字典将是您的应用程序通过 useIntlayer 钩子导入的最终结果。
关键概念
字典
字典是按键组织的结构化内容集合。每个字典包含:
- 键:字典的唯一标识符
- 内容:实际的内容值(文本、数字、对象等)
- 元数据:附加信息,如标题、描述、标签等
内容文件
内容文件示例:
复制代码到剪贴板
import { type ReactNode } from "react";
import {
t,
enu,
plural,
cond,
nest,
md,
html,
insert,
file,
type Dictionary,
} from "intlayer";
interface Content {
imbricatedContent: {
imbricatedContent2: {
stringContent: string; // 字符串内容
numberContent: number; // 数字内容
booleanContent: boolean; // 布尔内容
javaScriptContent: string; // JavaScript 内容
};
};
multilingualContent: string; // 多语言内容
quantityContent: string;
pluralContent: string; // 数量内容
conditionalContent: string; // 条件内容
markdownContent: never; // Markdown 内容
htmlContent: never; // HTML 内容
externalContent: string; // 外部内容
insertionContent: string; // 插入内容
nestedContent: string; // 嵌套内容
fileContent: string; // 文件内容
jsxContent: ReactNode; // JSX 内容
}
export default {
key: "page",
content: {
imbricatedContent: {
imbricatedContent2: {
stringContent: "Hello World",
numberContent: 123,
booleanContent: true,
javaScriptContent: `${process.env.NODE_ENV}`, // JavaScript 内容
},
},
multilingualContent: t({
zh: "中文内容",
en: "English content",
"en-GB": "English content (UK)",
fr: "French content",
es: "Spanish content",
}), // 多语言内容
quantityContent: enu({
"<-1": "少于负一辆车",
"-1": "负一辆车",
"0": "没有车",
"1": "一辆车",
">5": "几辆车",
">19": "许多车",
}),
pluralContent: plural({
one: "One car",
other: "{{count}} cars",
}), // 数量内容
conditionalContent: cond({
true: "验证已启用",
false: "验证已禁用",
}), // 条件内容
insertionContent: insert("你好 {{name}}!"), // 插入内容
nestedContent: nest(
"navbar", // 要嵌套的字典键
"login.button" // [可选] 要嵌套的内容路径
), // 嵌套内容
fileContent: file("./path/to/file.txt"), // 文件内容
externalContent: fetch("https://example.com").then((res) => res.json()), // 外部内容
markdownContent: md("# Markdown 示例"), // Markdown 内容
htmlContent: html("<p>Hello <strong>World</strong></p>"), // HTML 内容
/*
* 仅在使用 `react-intlayer` 或 `next-intlayer` 时可用
*/
jsxContent: <h1>我的标题</h1>, // JSX 内容
},
} satisfies Dictionary<Content>; // [可选] Dictionary 是泛型,允许您加强字典的格式化内容节点
内容节点是字典内容的构建块。它们可以是:
- 原始值:字符串、数字、布尔值、null、undefined
- 类型化节点:特殊内容类型,如翻译、条件、Markdown 等
- 函数:可在运行时计算的动态内容 参见函数获取
- 复数内容: 请参阅 复数内容 请参阅 复数内容
- 嵌套内容:对其他字典的引用
内容类型
Intlayer 通过类型化节点支持多种内容类型:
- 翻译内容:具有特定语言环境值的多语言文本 参见 翻译内容
- 条件内容:基于布尔表达式的条件内容 参见 条件内容
- 枚举内容:基于枚举值变化的内容 参见 枚举内容
- 插入内容:可以插入到其他内容中的内容 参见 插入内容
- Markdown 内容:以 Markdown 格式的富文本内容 参见 Markdown 内容
- HTML 内容:富 HTML 内容,可使用标准标签或自定义组件 参见 HTML 内容
- 嵌套内容:对其他字典的引用 参见 嵌套内容
- 性别内容:基于性别变化的内容 参见 性别内容
- 文件内容:对外部文件的引用 参见 文件内容
字典结构
Intlayer 中的字典由 Dictionary 类型定义,包含多个控制其行为的属性:
必需属性
key(字符串)
字典的标识符。如果多个字典具有相同的 key,Intlayer 会自动合并它们。
使用 kebab-case 命名规范(例如,"about-page-meta")。
Content(字符串 | 数字 | 布尔值 | 对象 | 数组 | 函数)
content 属性包含实际的字典数据,支持:
- 原始值:字符串、数字、布尔值、null、undefined
- 类型化节点:使用 Intlayer 辅助函数的特殊内容类型
- 嵌套对象:复杂的数据结构
- 数组:内容集合
- 函数:动态内容计算
可选属性
title(字符串)
字典的人类可读标题,有助于在编辑器和内容管理系统中识别字典。当管理大量字典或使用内容管理界面时,这一点尤其有用。
示例:
复制代码到剪贴板
{ key: "about-page-meta", title: "关于页面元数据", content: { /* ... */ }}description(字符串)
详细描述字典的用途、使用指南及任何特殊注意事项。此描述也用作 AI 驱动的翻译生成的上下文,有助于保持翻译质量和一致性。
示例:
复制代码到剪贴板
{ key: "about-page-meta", description: [ "该字典管理关于页面的元数据", "考虑SEO的最佳实践:", "- 标题应在50到60个字符之间", "- 描述应在150到160个字符之间", ].join('\n'), content: { /* ... */ }}tags (string[])
用于对字典进行分类和组织的字符串数组。标签提供了额外的上下文信息,可用于在编辑器和内容管理系统中进行过滤、搜索或组织字典。
示例:
复制代码到剪贴板
{ key: "about-page-meta", tags: ["metadata", "about-page", "seo"], content: { /* ... */ }}format ('intlayer' | 'icu' | 'i18next')
指定用于字典内容的格式化器。这允许使用不同的消息格式化语法。
'intlayer': 默认的 Intlayer 格式化器。'icu': 使用 ICU 消息格式化。'i18next': 使用 i18next 消息格式化。
示例:
复制代码到剪贴板
{ key: "my-dictionary", format: "icu", content: { message: "Hello {name}, you have {count, plural, one {# message} other {# messages}}" }}format ('intlayer' | 'icu' | 'i18next')
指定用于字典内容的格式化器。这允许使用不同的消息格式化语法。
'intlayer': 默认的 Intlayer 格式化器。'icu': 使用 ICU 消息格式化。'i18next': 使用 i18next 消息格式化。
示例:
复制代码到剪贴板
{ key: "my-dictionary", format: "icu", content: { message: "Hello {name}, you have {count, plural, one {# message} other {# messages}}" }}locale (LocalesValues)
将字典转换为按语言区域划分的字典,其中内容中声明的每个字段将自动转换为翻译节点。当设置此属性时:
- 该字典被视为单一语言环境字典
- 每个字段都会成为该特定语言环境的翻译节点
- 使用此属性时,内容中不应使用翻译节点(
t()) - 如果缺失,该字典将被视为多语言字典
更多信息请参见 Intlayer 中的按语言环境内容声明。
示例:
复制代码到剪贴板
// 按语言环境字典{ "key": "about-page", "locale": "en", "content": { "title": "关于我们", // 这将成为 'en' 的翻译节点 "description": "了解更多关于我们公司的信息" }}schema (SchemaKeys)
字典内容的架构。如果设置,内容将根据此架构进行验证。这允许您通过在 Intlayer 配置中定义的自定义验证架构来强制执行字典内容的特定结构。
示例:
复制代码到剪贴板
import { z } from "zod";export default { schemas: { "seo-metadata": z.object({ title: z.string().min(50).max(60), description: z.string().min(150).max(160), }), },};复制代码到剪贴板
import { type Dictionary } from "intlayer";const aboutPageMetaContent = { key: "about-page-meta", schema: "seo-metadata", content: { title: "About Our Company - Learn More About Us", description: "Discover our company's mission, values, and team.", },} satisfies Dictionary;export default aboutPageMetaContent;location ('local' | 'remote' | 'hybrid' | string)
指示字典的位置并控制其如何与 CMS 同步:
'local': 字典仅在本地管理。它不会被推送到远程 CMS。用于应保留在代码库中的内容。'remote': 字典仅在远程管理。推送到 CMS 后,它将与本地文件分离。在内容加载时,远程字典将从 CMS 拉取。带有remote位置的.content文件在初始推送后将被忽略。'hybrid': 字典在本地和远程同时管理。推送到 CMS 后,它将保持同步, 本地文件的更改会推送到 CMS,远程更改可以拉回本地文件。string(例如'plugin'):字典由插件或自定义源管理。当您尝试推送时,系统会询问您要执行的操作。
示例:
复制代码到剪贴板
{ key: "about-page", location: "local", // 内容仅保留在您的代码库中 content: { title: "About Us" }}autoFill (AutoFill)
自动从外部来源自动填充字典内容的说明。此功能可以在 intlayer.config.ts 中全局配置,也可以针对每个字典单独配置。支持多种格式:
true:为所有语言启用自动填充string:单个文件路径或带变量的模板路径object:按语言的文件路径配置
示例:
复制代码到剪贴板
// 为所有语言启用{ "autoFill": true}// 单个文件{ "autoFill": "./translations/aboutPage.content.json"}// 带变量的模板{ "autoFill": "/messages/{{locale}}/{{key}}/{{fileName}}.content.json"}// 细粒度的按语言配置{ "autoFill": { "en": "./translations/en/aboutPage.content.json", "fr": "./translations/fr/aboutPage.content.json", "es": "./translations/es/aboutPage.content.json" }}可用变量:
{{locale}}– 语言代码(例如fr,es){{fileName}}– 文件名(例如example){{key}}– 词典键(例如example)
更多信息请参见 Intlayer 中的自动填充配置。
priority(数字)
表示词典在冲突解决中的优先级。当多个词典包含相同键时,优先级数字最高的词典将覆盖其他词典。这对于管理内容层级和覆盖非常有用。
示例:
复制代码到剪贴板
// 基础词典{ key: "welcome-message", priority: 1, content: { message: "欢迎!" }}// 覆盖词典{ key: "welcome-message", priority: 10, content: { message: "欢迎使用我们的高级服务!" }}// 这将覆盖基础字典CMS 属性
version(字符串)
远程字典的版本标识符。帮助跟踪当前使用的字典版本,尤其在使用远程内容管理系统时非常有用。
importMode('static' | 'dynamic' | 'fetch')
导入模式决定字典在应用程序中的导入方式。
'static': 字典在构建时静态导入。这是默认模式。'dynamic': 字典在运行时使用 suspense API 动态导入。'fetch': 字典使用实时同步 API 动态导入。
如果设置,此属性将覆盖在 intlayer.config.ts 中定义的全局 importMode。
系统属性(自动生成)
这些属性由 Intlayer 自动生成,不应手动修改:
$schema(字符串)
用于验证字典结构的 JSON 模式。由 Intlayer 自动添加,以确保字典的完整性。
id(字符串)
对于远程字典,这是远程服务器中字典的唯一标识符。用于获取和管理远程内容。
localId(LocalDictionaryId)
本地字典的唯一标识符。由 Intlayer 自动生成,用于帮助识别字典并确定其是本地还是远程,以及其位置。
localIds(LocalDictionaryId[])
对于合并的字典,此数组包含所有被合并字典的 ID。对于追踪合并内容的来源非常有用。
filePath (string)
本地字典的文件路径,指示该字典是从哪个 .content 文件生成的。便于调试和源头追踪。
versions (string[])
对于远程字典,此数组包含字典的所有可用版本。帮助跟踪可用的版本。
autoFilled (true)
指示字典是否已从外部来源自动填充。在发生冲突时,基础字典将覆盖自动填充的字典。
内容节点类型
Intlayer 提供了几种扩展基本原始值的专用内容节点类型:
翻译内容 (t)
根据语言环境变化的多语言内容:
复制代码到剪贴板
import { t } from "intlayer";// TypeScript/JavaScriptmultilingualContent: t({ en: "Welcome to our website", fr: "Bienvenue sur notre site web", es: "Bienvenido a nuestro sitio web",});请参阅 翻译内容 (t) 文档 以获取更多信息。
条件内容 (cond)
基于布尔条件变化的内容:
复制代码到剪贴板
import { cond } from "intlayer";conditionalContent: cond({ true: "User is logged in", false: "Please log in to continue",});请参阅 条件内容 (cond) 文档 以获取更多信息。
枚举内容 (enu)
基于枚举值变化的内容:
复制代码到剪贴板
import { enu } from "intlayer";statusContent: enu({ pending: "您的请求正在处理中", approved: "您的请求已被批准", rejected: "您的请求已被拒绝",});请参阅 枚举内容 (enu) 文档 以获取更多信息。
Plural Content (plural)
Content that varies based on plural rules:
复制代码到剪贴板
import { plural } from "intlayer";pluralContent: plural({ one: "One car", other: "{{count}} cars",});请参阅 Plural Content 文档 以获取更多信息。### 插入内容 (insert)
可以插入到其他内容中的内容:
复制代码到剪贴板
import { insert } from "intlayer";insertionContent: insert("这段文本可以插入到任何地方");请参阅 插入内容 (insert) 文档 以获取更多信息。
嵌套内容 (nest)
引用其他字典:
复制代码到剪贴板
import { nest } from "intlayer";nestedContent: nest("about-page");请参阅 嵌套内容 (nest) 文档 以获取更多信息。
Markdown 内容 (md)
Markdown 格式的富文本内容:
复制代码到剪贴板
import { md } from "intlayer";markdownContent: md( "# 欢迎\n\n这是带有[链接](https://example.com)的**加粗**文本");请参阅 Markdown 内容 (md) 文档 以获取更多信息。
HTML 内容 (html)
可使用标准标签或自定义组件的富 HTML 内容:
复制代码到剪贴板
import { html, file, t } from "intlayer";// 内联 HTMLhtmlContent: html("<p>Hello <strong>World</strong></p>");// 从外部文件按语言环境使用 HTMLlocalizedHtmlContent: t({ zh: html(file("./content.zh.html")), en: html(file("./content.en.html")),});请参阅 HTML 内容 (html) 文档 以获取更多信息。
性别内容 (gender)
根据性别变化的内容:
复制代码到剪贴板
import { gender } from "intlayer";genderContent: gender({ male: "他是一名开发者", female: "她是一名开发者", other: "他们是一名开发者",});请参阅 性别内容 (gender) 文档 以获取更多信息。
文件内容 (file)
引用外部文件:
复制代码到剪贴板
import { file } from "intlayer";fileContent: file("./path/to/content.txt");请参阅 文件内容 (file) 文档 以获取更多信息。
创建内容文件
基本内容文件结构
内容文件导出一个满足 Dictionary 类型的默认对象:
复制代码到剪贴板
// example.content.tsimport { t, cond, nest, md, insert, file } from "intlayer";export default { key: "welcome-page", title: "欢迎页面内容", description: "主欢迎页面的内容,包括主视觉区域和功能", tags: ["页面", "欢迎", "主页"], content: { hero: { title: t({ zh: "欢迎来到我们的平台", en: "Welcome to Our Platform", fr: "Bienvenue sur Notre Plateforme", es: "Bienvenido a Nuestra Plataforma", }), subtitle: t({ zh: "轻松构建惊人的应用程序", en: "Build amazing applications with ease", fr: "Construisez des applications incroyables avec facilité", es: "Construye aplicaciones increíbles con facilidad", }), cta: cond({ true: t({ zh: "开始使用", en: "Get Started", fr: "Commencer", es: "Comenzar", }), false: t({ zh: "注册", en: "Sign Up", fr: "S'inscrire", es: "Registrarse", }), }), }, features: [ { title: t({ zh: "易于使用", en: "Easy to Use", fr: "Facile à Utiliser", es: "Fácil de Usar", }), description: t({ zh: "适合所有技能水平的直观界面", en: "Intuitive interface for all skill levels", fr: "Interface intuitive pour tous les niveaux", es: "Interfaz intuitiva para todos los niveles", }), }, ], documentation: nest("documentation"), readme: file("./README.md"), },} satisfies Dictionary;JSON 内容文件
您也可以创建 JSON 格式的内容文件:
复制代码到剪贴板
{ "key": "welcome-page", "title": "欢迎页面内容", "description": "主欢迎页面的内容", "tags": ["页面", "欢迎"], "content": { "hero": { "title": { "nodeType": "translation", "translation": { "en": "欢迎来到我们的平台", "fr": "Bienvenue sur Notre Plateforme" } }, "subtitle": { "nodeType": "translation", "translation": { "en": "轻松构建惊人的应用程序", "fr": "Construisez des applications incroyables avec facilité" } } } }}Markdown 内容文件
复制代码到剪贴板
---key: welcome-pagelocale: entitle: Welcome Page Contentdescription: Content for the main welcome pagetags: - page - welcome---# Welcome to Our Platform## Build amazing applications with easeYAML 内容文件
复制代码到剪贴板
key: welcome-pagetitle: Welcome Page Contentdescription: Content for the main welcome pagelocale: "en"tags: - page - welcomecontent: hero: title: Welcome to Our Platform subtitle: Build amazing applications with ease每语言内容文件
对于每语言字典,指定 locale 属性:
复制代码到剪贴板
// welcome-page.en.content.tsexport default { key: "welcome-page", locale: "en", content: { hero: { title: "欢迎来到我们的平台", subtitle: "轻松构建惊人的应用程序", }, },} satisfies Dictionary;复制代码到剪贴板
// welcome-page.fr.content.tsexport default { key: "welcome-page", locale: "fr", content: { hero: { title: "欢迎使用我们的平台", subtitle: "轻松构建惊人的应用程序", }, },} satisfies Dictionary;内容文件扩展名
Intlayer 允许您自定义内容声明文件的扩展名。此自定义功能为管理大型项目提供了灵活性,并有助于避免与其他模块的冲突。
默认扩展名
默认情况下,Intlayer 会监视所有具有以下扩展名的文件作为内容声明:
.content.json.content.json5.content.jsonc.content.ts.content.tsx.content.js.content.jsx.content.mjs.content.mjx.content.cjs.content.cjx.content.md.content.mdx.content.yaml.content.yml
这些默认的扩展名适用于大多数应用程序。然而,当您有特定需求时,可以定义自定义扩展名,以简化构建过程并减少与其他组件冲突的风险。
要自定义 Intlayer 用于识别内容声明文件的文件扩展名,您可以在 Intlayer 配置文件中指定它们。这种方法对于大型项目非常有用,因为限制监视过程的范围可以提升构建性能。
高级概念
字典合并
当多个字典具有相同的键时,Intlayer 会自动合并它们。合并行为取决于多个因素:
- 优先级:具有更高
priority值的字典会覆盖优先级较低的字典 - 自动填充与基础:基础字典会覆盖自动填充的字典
- 位置:本地字典会覆盖远程字典(当优先级相同时)
类型安全
Intlayer 为内容文件提供完整的 TypeScript 支持:
复制代码到剪贴板
// 定义你的内容类型interface WelcomePageContent { hero: { title: string; subtitle: string; cta: string; }; features: Array<{ title: string; description: string; }>;}// 在字典中使用它export default { key: "welcome-page", content: { // TypeScript 将提供自动补全和类型检查 hero: { title: "欢迎", subtitle: "构建惊人的应用", cta: "开始使用", }, },} satisfies Dictionary<WelcomePageContent>;节点嵌套
你可以毫无问题地将函数嵌套到其他函数中。
示例:
复制代码到剪贴板
import { t, enu, cond, nest, md, type Dictionary } from "intlayer";
const getName = async () => "John Doe";
export default {
key: "page",
content: {
// `getIntlayer('page','en').hiMessage` 返回 `['Hi', ' ', 'John Doe']`
hiMessage: [
t({
en: "Hi",
fr: "Salut",
es: "Hola",
}),
" ",
getName(),
],
// 复合内容,嵌套条件、枚举和多语言内容
// `getIntlayer('page','en').advancedContent(true)(10)` 返回 'Multiple items found'
advancedContent: cond({
true: enu({
"0": t({
en: "No items found",
fr: "Aucun article trouvé",
es: "No se encontraron artículos",
}),
"1": t({
en: "One item found",
fr: "Un article trouvé",
es: "Se encontró un artículo",
}),
">1": t({
en: "Multiple items found",
fr: "Plusieurs articles trouvés",
es: "Se encontraron múltiples artículos",
}),
}),
false: t({
en: "No valid data available",
fr: "Aucune donnée valide disponible",
es: "No hay datos válidos disponibles",
}),
}),
},
} satisfies Dictionary;最佳实践
命名规范:
- 对字典键使用kebab-case(例如
"about-page-meta") - 将相关内容归类到相同的键前缀下
- 对字典键使用kebab-case(例如
内容组织:
- 将相关内容保存在同一个字典中
- 使用嵌套对象来组织复杂的内容结构
- 利用标签进行分类
- 使用
autoFill自动填充缺失的翻译
性能:
- 调整内容配置以限制监视文件的范围
- 仅在需要实时更新时使用实时字典(例如 A/B 测试等)
- 确保启用构建转换插件(
@intlayer/swc或@intlayer/babel)以在构建时优化字典