Ask your question and get a summary of the document by referencing this page and the AI provider of your choice
Version History
- "Introduce select based content"v9.1.07/30/2026
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
Select-Based Content / Select in Intlayer
How Select Works
In Intlayer, select-based content is achieved through the select function, which maps arbitrary string values to their corresponding content. It is the equivalent of an ICU {value, select, …} message, or of a switch statement in your application code.
Use select when the discriminant is a free-form string — a status, a plan, a platform, a role. For the other discriminants, Intlayer provides dedicated nodes:
Open the table in a modal to view all data content clearly
| Discriminant | Node |
|---|---|
| A quantity | enu() |
| A boolean | cond() |
| A gender | gender() |
| Any other string value | select() |
Setting Up Select-Based Content
To set up select-based content in your Intlayer project, create a content module that includes your select definitions. Below are examples in various formats.
Copy the code to the clipboard
import { select, type Dictionary } from "intlayer";
const myPostContent = {
key: "my_key",
content: {
publishStatus: select({
draft: "This post is a draft",
published: "This post is live",
scheduled: "This post is scheduled",
fallback: "Unknown status", // Optional
}),
},
} satisfies Dictionary;
export default myPostContent;If nofallbackis declared, the last key declared will be taken as a fallback when the provided value matches no declared case — the same contract ascond()andgender().
Type safety
The accepted argument is inferred from the declared cases:
- Without a
fallback, only the declared cases are accepted — a typo is a type error. - With a
fallback, any string is accepted (the fallback covers the unmatched values) while the declared cases still autocomplete.
Why not a plain object?
It is tempting to declare a plain object and index it with the runtime value:
Copy the code to the clipboard
// ❌ Do not do thisconst { publishStatus } = useIntlayer("my_key");return <p>{publishStatus[publishType]}</p>;The Intlayer compiler analyses your source to prune unused content and minify the remaining keys. A dynamic computed access (obj[expr]) cannot be resolved statically, so the whole branch is marked opaque: it is kept in the bundle and its keys stay un-minified.
With select(), the case resolution happens inside a function call rather than as a property access. The compiler sees a single static field access and optimises the node exactly like enu(), cond() or gender():
Copy the code to the clipboard
// ✅ Do thisconst { publishStatus } = useIntlayer("my_key");return <p>{publishStatus(publishType)}</p>;Using Select-Based Content
To utilize select-based content within a React component, import and use the useIntlayer hook from the react-intlayer package. This hook fetches the content for the specified key and allows you to pass in a value to select the appropriate output.
Copy the code to the clipboard
import type { FC } from "react";
import { useIntlayer } from "react-intlayer";
const PostStatus: FC = () => {
const { publishStatus } = useIntlayer("my_key");
return (
<div>
<p>
{
/* Output: This post is a draft */
publishStatus("draft")
}
</p>
<p>
{
/* Output: This post is live */
publishStatus("published")
}
</p>
<p>
{
/* Output: Unknown status */
publishStatus("archived")
}
</p>
</div>
);
};
export default PostStatus;Combining Select with Other Nodes
Each case holds a full content node, so select composes with t(), insert(), md() and the others:
Copy the code to the clipboard
import { insert, select, t, type Dictionary } from "intlayer";const myPostContent = { key: "my_key", content: { publishStatus: select({ draft: insert( t({ en: "{{name}} saved a draft", fr: "{{name}} a enregistré un brouillon", }) ), published: insert( t({ en: "{{name}} published the post", fr: "{{name}} a publié l’article", }) ), fallback: insert( t({ en: "{{name}} updated the post", fr: "{{name}} a mis à jour l’article", }) ), }), },} satisfies Dictionary;export default myPostContent;Copy the code to the clipboard
publishStatus("draft")({ name: "Alice" }); // Output: Alice saved a draftMigrating from ICU select
Messages using the ICU select argument are imported as select nodes:
Copy the code to the clipboard
{publishType, select, draft {draft} published {published} other {Unknown}}becomes
Copy the code to the clipboard
select( { draft: "draft", published: "published", fallback: "Unknown", }, "publishType");The ICU other case is renamed to fallback, which is Intlayer's canonical name for a catch-all. The second argument records the ICU variable name so the message round-trips back to the exact same ICU string when exported.
An ICUselectwhose cases are gender values (male/female/other) is imported as agendernode instead.
Additional Resources
For more detailed information on configuration and usage, refer to the following resources:
These resources offer further insights into the setup and usage of Intlayer across various environments and frameworks.