--- createdAt: 2026-06-12 updatedAt: 2026-06-12 title: 动态记录 description: 在 Intlayer 内容文件中使用 meta 字段来声明在运行时通过不透明 ID 获取的 CMS 管理记录,从而实现强类型的动态内容,而无需在构建时进行枚举。 keywords: - 动态记录 - 动态内容 - CMS - 运行时内容 - Intlayer - 国际化 slugs: - doc - concept - dynamic-records history: - version: 9.0.0 date: 2026-06-12 changes: "发布动态内容功能" author: aymericzip --- # 动态记录 **动态记录**(dynamic record)是指其唯一身份标识不是顺序索引或命名变体,而是在 `meta` 字段中声明的任意键值对集合的内容文件。Intlayer 将在运行时使用这些字段作为选择器,从而可以定位 CMS 记录、用户特定文案或任何在构建时未知其键的内容。 ## 声明动态记录 ```ts fileName="product-copy.abc.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]} 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; ``` ```ts fileName="product-copy.abcd.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]} 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 报错。 ```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]} import { useIntlayer } from "react-intlayer"; export const ProductCopy = ({ productId, userId, }: { productId: string; userId: string; }) => { const content = useIntlayer("product-copy", { id: productId, userId }); // TypeScript 会强制要求同时提供 `id` 和 `userId`。 if (!content) return null; return

{content.description}

; }; ```
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]} import { useIntlayer } from "next-intlayer"; export const ProductCopy = ({ productId, userId, }: { productId: string; userId: string; }) => { const content = useIntlayer("product-copy", { id: productId, userId }); // TypeScript 会强制要求同时提供 `id` 和 `userId`。 if (!content) return null; return

{content.description}

; }; ```
```vue fileName="ProductCopy.vue" contentDeclarationFormat={["typescript", "esm", "commonjs"]} ``` ```svelte fileName="ProductCopy.svelte" contentDeclarationFormat={["typescript", "esm", "commonjs"]} {#if $content}

{$content.description}

{/if} ```
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]} import { useIntlayer } from "preact-intlayer"; export const ProductCopy = ({ productId, userId, }: { productId: string; userId: string; }) => { const content = useIntlayer("product-copy", { id: productId, userId }); // TypeScript 会强制要求同时提供 `id` 和 `userId`。 if (!content) return null; return

{content.description}

; }; ```
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]} import { useIntlayer } from "solid-intlayer"; export const ProductCopy = (props: { productId: string; userId: string; }) => { const content = useIntlayer("product-copy", { id: props.productId, userId: props.userId }); // TypeScript 会强制要求同时提供 `id` 和 `userId`。 return ( <> {content() &&

{content().description}

} ); }; ```
```typescript fileName="product-copy.component.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]} import { Component, Input, OnInit } from "@angular/core"; import { useIntlayer } from "angular-intlayer"; @Component({ selector: "app-product-copy", template: ` @if (content()) {

{{ content().description }}

} `, }) export class ProductCopyComponent implements OnInit { @Input() productId!: string; @Input() userId!: string; content: any; ngOnInit() { this.content = useIntlayer("product-copy", { id: this.productId, userId: this.userId }); } } ```
```javascript fileName="product-copy.js" import { useIntlayer } from "vanilla-intlayer"; const content = useIntlayer("product-copy", { id: "prod_abcd", userId: "user_123" }); if (content) { document.body.innerHTML = `

${content.description}

`; } ```
### 使用显式语言环境 ```tsx const content = useIntlayer("product-copy", { id: "prod_abc", userId: "user_123", locale: "zh", }); ``` ### 缺少 meta 字段 — 编译时错误 ```ts // 类型错误:缺少 `userId` const content = useIntlayer("product-copy", { id: "prod_abc" }); ``` ## 加载模式 (loading mode) 动态记录通常采用延迟加载方式。在字典中设置 `importMode` 来控制此行为: ```ts contentDeclarationFormat={["typescript", "esm", "commonjs"]} const dictionary = { key: "product-copy", importMode: "fetch", // 或 "dynamic" meta: { id: "prod_abc", userId: "user_123" }, content: { … }, } satisfies Dictionary; export default dictionary; ``` 关于 `static`、`dynamic` 和 `fetch` 模式的详细信息,请参阅[分包优化](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/bundle_optimization.md)。 ## 典型使用场景 - 在 CMS 中管理的单件商品营销文案 - 用户特定或账户特定的内容 - 在运行时通过不透明 ID 标识的任何内容