Ask your question and get a summary of the document by referencing this page and the AI provider of your choice
By integrating the Intlayer MCP Server to your favourite AI assistant can retrieve all the doc directly from ChatGPT, DeepSeek, Cursor, VSCode, etc.
See MCP Server docThe content of this page was translated using an AI.
See the last version of the original content in EnglishIf 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
Content File
<iframe title="i18n, Markdown, JSON… one single solution to manage it all | Intlayer" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/1VHgSY_j9_I?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
What is a Content File?
A content file in Intlayer is a file that contains dictionary definitions.
These files declare your application's text content, translations, and resources.
Content files are processed by Intlayer to generate dictionaries.
The dictionaries will be the final result that your application will import using the useIntlayer hook.
Key Concepts
Dictionary
A dictionary is a structured collection of content organised by keys. Each dictionary contains:
- Key: A unique identifier for the dictionary
- Content: The actual content values (text, numbers, objects, etc.)
- Metadata: Additional information like title, description, tags, etc.
Content File
Content file example:
Copy the code to the clipboard
import { type ReactNode } from "react";import { t, enu, cond, nest, md, insert, file, type Dictionary,} from "intlayer";interface Content { imbricatedContent: { imbricatedContent2: { stringContent: string; numberContent: number; booleanContent: boolean; javaScriptContent: string; }; }; multilingualContent: string; quantityContent: string; conditionalContent: string; markdownContent: never; externalContent: string; insertionContent: string; nestedContent: string; fileContent: string; jsxContent: ReactNode;}export default { key: "page", content: { imbricatedContent: { imbricatedContent2: { stringContent: "Hello World", numberContent: 123, booleanContent: true, javaScriptContent: `${process.env.NODE_ENV}`, }, }, multilingualContent: t({ "en-GB": "English content (UK)", en: "English content", fr: "French content", es: "Spanish content", }), quantityContent: enu({ "<-1": "Less than minus one car", "-1": "Minus one car", "0": "No cars", "1": "One car", ">5": "Some cars", ">19": "Many cars", }), conditionalContent: cond({ true: "Validation is enabled", false: "Validation is disabled", }), insertionContent: insert("Hello {{name}}!"), nestedContent: nest( "navbar", // The key of the dictionary to nest "login.button" // [Optional] The path to the content to nest ), fileContent: file("./path/to/file.txt"), externalContent: fetch("https://example.com").then((res) => res.json()), markdownContent: md("# Markdown Example"), /* * Only available using `react-intlayer` or `next-intlayer` */ jsxContent: <h1>My title</h1>, },} satisfies Dictionary<Content>; // [optional] Dictionary is generic and allows you to strengthen the formatting of your dictionary
Content Nodes
Content nodes are the building blocks of dictionary content. They can be:
- Primitive values: strings, numbers, booleans, null, undefined
- Typed nodes: Special content types such as translations, conditions, markdown, etc.
- Functions: Dynamic content that can be evaluated at runtime see Function Fetching
- Nested content: References to other dictionaries
Content Types
Intlayer supports various content types through typed nodes:
- Translation Content: Multilingual text with locale-specific values see Translation Content
- Condition Content: Conditional content based on boolean expressions see Condition Content
- Enumeration Content: Content that varies based on enumerated values see Enumeration Content
- Insertion Content: Content that can be inserted into other content see Insertion Content
- Markdown Content: Rich text content in Markdown format see Markdown Content
- Nested Content: References to other dictionaries see Nested Content
- Gender Content: Content that varies based on gender see Gender Content
- File Content: References to external files see File Content
Dictionary Structure
A dictionary in Intlayer is defined by the Dictionary type and contains several properties that control its behaviour:
Required Properties
key (string)
The identifier for the dictionary. If multiple dictionaries have the same key, Intlayer will merge them automatically.
Use kebab-case naming convention (e.g., "about-page-meta").
Content (string | number | boolean | object | array | function)
The content property contains the actual dictionary data and supports:
- Primitive values: strings, numbers, booleans, null, undefined
- Typed nodes: Special content types using Intlayer's helper functions
- Nested objects: Complex data structures
- Arrays: Collections of content
- Functions: Dynamic content evaluation
Optional Properties
title (string)
Human-readable title for the dictionary that helps identify it in editors and CMS systems. This is particularly useful when managing large numbers of dictionaries or when working with content management interfaces.
Example:
{ key: "about-page-meta", title: "About Page Metadata", content: { /* ... */ }}
description (string)
Detailed description explaining the dictionary's purpose, usage guidelines, and any special considerations. This description is also used as context for AI-powered translation generation, making it valuable for maintaining translation quality and consistency.
Example:
{ key: "about-page-meta", description: [ "This dictionary manages the metadata of the About Page", "Consider good practices for SEO:", "- The title should be between 50 and 60 characters", "- The description should be between 150 and 160 characters", ].join('\n'), content: { /* ... */ }}
tags (string[])
Array of strings for categorising and organising dictionaries. Tags provide additional context and can be used for filtering, searching, or organising dictionaries in editors and CMS systems.
Example:
{ key: "about-page-meta", tags: ["metadata", "about-page", "seo"], content: { /* ... */ }}
locale (LocalesValues)
Transforms the dictionary into a per-locale dictionary where each field declared in the content will be automatically transformed into a translation node. When this property is set:
- The dictionary is treated as a single-locale dictionary
- Each field becomes a translation node for that specific locale
- You should NOT use translation nodes (t()) in the content when using this property
- If missing, the dictionary will be treated as a multilingual dictionary
See Per-Locale Content Declaration in Intlayer for more information.
Example:
// Per-locale dictionary{ "key": "about-page", "locale": "en", "content": { "title": "About Us", // This becomes a translation node for 'en' "description": "Learn more about our company" }}
autoFill (AutoFill)
Instructions for automatically filling dictionary content from external sources. This can be configured globally in intlayer.config.ts or per dictionary. Supports multiple formats:
- true: Enable auto-fill for all locales
- string: Path to a single file or template with variables
- object: Per-locale file paths
Examples:
// Enable for all locales{ "autoFill": true}// Single file{ "autoFill": "./translations/aboutPage.content.json"}// Template with variables{ "autoFill": "/messages/{{locale}}/{{key}}/{{fileName}}.content.json"}// Fine per-locale configuration{ "autoFill": { "en": "./translations/en/aboutPage.content.json", "fr": "./translations/fr/aboutPage.content.json", "es": "./translations/es/aboutPage.content.json" }}
Available variables:
- {{locale}} – Locale code (e.g. fr, es)
- {{fileName}} – File name (e.g. example)
- {{key}} – Dictionary key (e.g. example)
See Auto-Fill Configuration in Intlayer for more information.
priority (number)
Indicates the priority of the dictionary for conflict resolution. When multiple dictionaries have the same key, the dictionary with the highest priority number will override the others. This is useful for managing content hierarchies and overrides.
Example:
// Base dictionary{ key: "welcome-message", priority: 1, content: { message: "Welcome!" }}// Override dictionary{ key: "welcome-message", priority: 10, content: { message: "Welcome to our premium service!" }}// This will override the base dictionary
CMS Properties
version (string)
Version identifier for remote dictionaries. Helps track which version of the dictionary is currently being used, especially useful when working with remote content management systems.
live (boolean)
For remote dictionaries, indicates if the dictionary should be fetched live at runtime. When enabled:
- Requires importMode to be set to "live" in intlayer.config.ts
- Requires a live server to be running
- Dictionary will be fetched at runtime using the live sync API
- If live but fetch fails, falls back to dynamic value
- If not live, dictionary is transformed at build time for optimal performance
System Properties (Auto-generated)
These properties are automatically generated by Intlayer and should not be manually modified:
$schema (string)
JSON schema used for validation of the dictionary structure. Automatically added by Intlayer to ensure dictionary integrity.
id (string)
For remote dictionaries, this is the unique identifier of the dictionary on the remote server. Used for fetching and managing remote content.
localId (LocalDictionaryId)
Unique identifier for local dictionaries. Auto-generated by Intlayer to help identify the dictionary and determine if it is local or remote, along with its location.
localIds (LocalDictionaryId[])
For merged dictionaries, this array contains the IDs of all dictionaries that were merged together. Useful for tracking the source of merged content.
filePath (string)
The file path of the local dictionary, indicating which .content file the dictionary was generated from. Helps with debugging and source tracking.
versions (string[])
For remote dictionaries, this array contains all available versions of the dictionary. Helps track which versions are available for use.
autoFilled (true)
Indicates whether the dictionary has been auto-filled from external sources. In case of conflicts, base dictionaries will override auto-filled dictionaries.
location ('distant' | 'locale')
Indicates the location of the dictionary:
- 'locale': Local dictionary (from content files)
- 'distant': Remote dictionary (from external source)
Content Node Types
Intlayer provides several specialised content node types that extend basic primitive values:
Translation Content (t)
Multilingual content that varies by locale:
import { t } from "intlayer";// TypeScript/JavaScriptmultilingualContent: t({ en: "Welcome to our website", fr: "Bienvenue sur notre site web", es: "Bienvenido a nuestro sitio web",});
Condition Content (cond)
Content that changes based on boolean conditions:
import { cond } from "intlayer";conditionalContent: cond({ true: "User is logged in", false: "Please log in to continue",});
Enumeration Content (enu)
Content that varies based on enumerated values:
import { enu } from "intlayer";statusContent: enu({ pending: "Your request is pending", approved: "Your request has been approved", rejected: "Your request has been rejected",});
Insertion Content (insert)
Content that can be inserted into other content:
import { insert } from "intlayer";insertionContent: insert("This text can be inserted anywhere");
Nested Content (nest)
References to other dictionaries:
import { nest } from "intlayer";nestedContent: nest("about-page");
Markdown Content (md)
Rich text content in Markdown format:
import { md } from "intlayer";markdownContent: md( "# Welcome\n\nThis is **bold** text with [links](https://example.com)");
Gender Content (gender)
Content that varies based on gender:
import { gender } from "intlayer";genderContent: gender({ male: "He is a developer", female: "She is a developer", other: "They are a developer",});
File Content (file)
References to external files:
import { file } from "intlayer";fileContent: file("./path/to/content.txt");
Creating Content Files
Basic Content File Structure
A content file exports a default object that satisfies the Dictionary type:
// example.content.tsimport { t, cond, nest, md, insert, file } from "intlayer";export default { key: "welcome-page", title: "Welcome Page Content", description: "Content for the main welcome page including hero section and features", tags: ["page", "welcome", "homepage"], content: { hero: { title: t({ "en-GB": "Welcome to Our Platform", en: "Welcome to Our Platform", fr: "Bienvenue sur Notre Plateforme", es: "Bienvenido a Nuestra Plataforma", }), subtitle: t({ "en-GB": "Build amazing applications with ease", en: "Build amazing applications with ease", fr: "Construisez des applications incroyables avec facilité", es: "Construye aplicaciones increíbles con facilidad", }), cta: cond({ true: t({ "en-GB": "Get Started", en: "Get Started", fr: "Commencer", es: "Comenzar", }), false: t({ "en-GB": "Sign Up", en: "Sign Up", fr: "S'inscrire", es: "Registrarse", }), }), }, features: [ { title: t({ "en-GB": "Easy to Use", en: "Easy to Use", fr: "Facile à Utiliser", es: "Fácil de Usar", }), description: t({ "en-GB": "Intuitive interface for all skill levels", 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 Content File
You can also create content files in JSON format:
{ "key": "welcome-page", "title": "Welcome Page Content", "description": "Content for the main welcome page", "tags": ["page", "welcome"], "content": { "hero": { "title": { "nodeType": "translation", "translation": { "en-GB": "Welcome to Our Platform", "en": "Welcome to Our Platform", "fr": "Bienvenue sur Notre Plateforme" } }, "subtitle": { "nodeType": "translation", "translation": { "en-GB": "Build amazing applications with ease", "en": "Build amazing applications with ease", "fr": "Construisez des applications incroyables avec facilité" } } } }}
Per-Locale Content Files
For per-locale dictionaries, specify the locale property:
// welcome-page.en-GB.content.tsexport default { key: "welcome-page", locale: "en-GB", content: { hero: { title: "Welcome to Our Platform", subtitle: "Build amazing applications with ease", }, },} satisfies Dictionary;
// welcome-page.fr.content.tsexport default { key: "welcome-page", locale: "fr", content: { hero: { title: "Bienvenue sur Notre Plateforme", subtitle: "Construisez des applications incroyables avec facilité", }, },} satisfies Dictionary;
Content File Extensions
Intlayer allows you to customise the extensions for your content declaration files. This customisation provides flexibility in managing large-scale projects and helps to avoid conflicts with other modules.
Default Extensions
By default, Intlayer watches all files with the following extensions for content declarations:
- .content.json
- .content.ts
- .content.tsx
- .content.js
- .content.jsx
- .content.mjs
- .content.mjx
- .content.cjs
- .content.cjx
These default extensions are suitable for most applications. However, when you have specific requirements, you can define custom extensions to streamline the build process and reduce the risk of conflicts with other components.
To customise the file extensions Intlayer uses to identify content declaration files, you can specify them in the Intlayer configuration file. This approach is beneficial for large-scale projects where limiting the scope of the watch process improves build performance.
Advanced Concepts
Dictionary Merging
When multiple dictionaries have the same key, Intlayer automatically merges them. The merging behaviour depends on several factors:
- Priority: Dictionaries with higher priority values override those with lower values
- Auto-fill vs Base: Base dictionaries override auto-filled dictionaries
- Location: Local dictionaries override remote dictionaries (when priorities are equal)
Type Safety
Intlayer provides full TypeScript support for content files:
// Define your content typeinterface WelcomePageContent { hero: { title: string; subtitle: string; cta: string; }; features: Array<{ title: string; description: string; }>;}// Use it in your dictionaryexport default { key: "welcome-page", content: { // TypeScript will provide autocomplete and type checking hero: { title: "Welcome", subtitle: "Build amazing apps", cta: "Get Started", }, },} satisfies Dictionary<WelcomePageContent>;
Node Imbrication
You can without problem imbricate functions into other ones.
Example :
Copy the code to the clipboard
import { t, enu, cond, nest, md, type Dictionary } from "intlayer";const getName = async () => "John Doe";export default { key: "page", content: { // `getIntlayer('page','en').hiMessage` returns `['Hi', ' ', 'John Doe']` hiMessage: [ t({ 'en-GB': "Hi", en: "Hi", fr: "Salut", es: "Hola", }), " ", getName(), ], // Composite content imbricating condition, enumeration, and multilingual content // `getIntlayer('page','en').advancedContent(true)(10) returns 'Multiple items found'` advancedContent: cond({ true: enu({ "0": t({ 'en-GB': "No items found", 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-GB': "No valid data available", en: "No valid data available", fr: "Aucune donnée valide disponible", es: "No hay datos válidos disponibles", }), }), },} satisfies Dictionary;
Best Practices
Naming Conventions:
- Use kebab-case for dictionary keys ("about-page-meta")
- Group related content under the same key prefix
Content Organisation:
- Keep related content together in the same dictionary
- Use nested objects to organise complex content structures
- Leverage tags for categorisation
- Use the autoFill to automatically fill the missing translations
Performance:
- Adjust the content configuration to limit the scope of watched files
- Use live dictionaries only when real-time updates are necessary, (e.g. A/B testing, etc.)
- Ensure the build transformation plugin (@intlayer/swc, or @intlayer/babel) is enabled to optimise the dictionary at build time
Doc History
Version | Date | Changes |
---|---|---|
6.0.0 | 2025-09-20 | Add fields documentation |
5.5.10 | 2025-06-29 | Init history |