\n\n \n {{ content.description }}
\n \n ```\n\n \n \n ```svelte fileName=\"ProductCopy.svelte\" contentDeclarationFormat={[\"typescript\", \"esm\", \"commonjs\"]}\n \n\n {#if $content}\n {$content.description}
\n {/if}\n ```\n\n \n \n ```tsx fileName=\"ProductCopy.tsx\" contentDeclarationFormat={[\"typescript\", \"esm\", \"commonjs\"]}\n import { useIntlayer } from \"preact-intlayer\";\n\n export const ProductCopy = ({\n productId,\n userId,\n }: {\n productId: string;\n userId: string;\n }) => {\n const content = useIntlayer(\"product-copy\", { id: productId, userId });\n // TypeScript 会强制要求同时提供 `id` 和 `userId`。\n\n if (!content) return null;\n\n return {content.description}
;\n };\n ```\n\n \n \n ```tsx fileName=\"ProductCopy.tsx\" contentDeclarationFormat={[\"typescript\", \"esm\", \"commonjs\"]}\n import { useIntlayer } from \"solid-intlayer\";\n\n export const ProductCopy = (props: {\n productId: string;\n userId: string;\n }) => {\n const content = useIntlayer(\"product-copy\", { id: props.productId, userId: props.userId });\n // TypeScript 会强制要求同时提供 `id` 和 `userId`。\n\n return (\n <>\n {content() && {content().description}
}\n >\n );\n };\n ```\n\n \n \n ```typescript fileName=\"product-copy.component.ts\" contentDeclarationFormat={[\"typescript\", \"esm\", \"commonjs\"]}\n import { Component, Input, OnInit } from \"@angular/core\";\n import { useIntlayer } from \"angular-intlayer\";\n\n @Component({\n selector: \"app-product-copy\",\n template: `\n @if (content()) {\n {{ content().description }}
\n }\n `,\n })\n export class ProductCopyComponent implements OnInit {\n @Input() productId!: string;\n @Input() userId!: string;\n\n content: any;\n\n ngOnInit() {\n this.content = useIntlayer(\"product-copy\", { id: this.productId, userId: this.userId });\n }\n }\n ```\n\n \n \n ```javascript fileName=\"product-copy.js\"\n import { useIntlayer } from \"vanilla-intlayer\";\n\n const content = useIntlayer(\"product-copy\", {\n id: \"prod_abcd\",\n userId: \"user_123\"\n });\n\n if (content) {\n document.body.innerHTML = `${content.description}
`;\n }\n ```\n\n \n\n\n### 使用显式语言环境\n\n```tsx\nconst content = useIntlayer(\"product-copy\", {\n id: \"prod_abc\",\n userId: \"user_123\",\n locale: \"zh\",\n});\n```\n\n### 缺少 meta 字段 — 编译时错误\n\n```ts\n// 类型错误:缺少 `userId`\nconst content = useIntlayer(\"product-copy\", { id: \"prod_abc\" });\n```\n\n## 加载模式 (loading mode)\n\n动态记录通常采用延迟加载方式。在字典中设置 `importMode` 来控制此行为:\n\n```ts contentDeclarationFormat={[\"typescript\", \"esm\", \"commonjs\"]}\nconst dictionary = {\n key: \"product-copy\",\n importMode: \"fetch\", // 或 \"dynamic\"\n meta: { id: \"prod_abc\", userId: \"user_123\" },\n content: { … },\n} satisfies Dictionary;\n\nexport default dictionary;\n```\n\n关于 `static`、`dynamic` 和 `fetch` 模式的详细信息,请参阅[分包优化](/zh/doc/concept/bundle-optimization)。\n\n## 典型使用场景\n\n- 在 CMS 中管理的单件商品营销文案\n- 用户特定或账户特定的内容\n- 在运行时通过不透明 ID 标识的任何内容\n","description":"在 Intlayer 内容文件中使用 meta 字段来声明在运行时通过不透明 ID 获取的 CMS 管理记录,从而实现强类型的动态内容,而无需在构建时进行枚举。","url":"https://intlayer.org/zh/doc/concept/dynamic-records","datePublished":"2026-06-12","dateModified":"2026-06-12","version":"9.0.0","keywords":"动态记录, 动态内容, CMS, 运行时内容, Intlayer, 国际化","license":"https://raw.githubusercontent.com/aymericzip/intlayer/refs/heads/main/LICENSE","audience":{"@type":"Audience","audienceType":"开发者,内容经理"}}
作者: Creation:2026-06-12Last update:2026-06-12
动态记录
动态记录(dynamic record)是指其唯一身份标识不是顺序索引或命名变体,而是在 meta 字段中声明的任意键值对集合的内容文件。Intlayer 将在运行时使用这些字段作为选择器,从而可以定位 CMS 记录、用户特定文案或任何在构建时未知其键的内容。
声明动态记录
product-copy.abc.content.ts import { t, type Dictionary } from "intlayer";
const dictionary = {
key: "product-copy",
meta: {
id: "prod_abc",
userId: "user_123",
},
content: {
name: t({ en: "Widget Pro", fr: "Widget Pro" }),
description: t({ en: "The best widget.", fr: "Le meilleur widget." }),
},
} satisfies Dictionary;
export default dictionary;
product-copy.abcd.content.ts import { t, type Dictionary } from "intlayer";
const dictionary = {
key: "product-copy",
meta: {
id: "prod_abcd",
userId: "user_123",
},
content: {
name: t({ en: "Widget Lite", fr: "Widget Lite" }),
description: t({ en: "A lighter option.", fr: "Une option plus légère." }),
},
} satisfies Dictionary;
export default dictionary;
使用动态记录
选择器中所有的 meta 字段都是必填的。省略任何字段都将返回 null 并导致 TypeScript 报错。
使用显式语言环境
加载模式 (loading mode)
动态记录通常采用延迟加载方式。在字典中设置 importMode 来控制此行为:
const dictionary = {
key: "product-copy",
importMode: "fetch", // 或 "dynamic"
meta: { id: "prod_abc", userId: "user_123" },
content: { … },
} satisfies Dictionary;
export default dictionary;
关于 static、dynamic 和 fetch 模式的详细信息,请参阅分包优化。
典型使用场景
- 在 CMS 中管理的单件商品营销文案
- 用户特定或账户特定的内容
- 在运行时通过不透明 ID 标识的任何内容