Ask your question and get a summary of the document by referencing this page and the AI provider of your choice
Version History
- "Init history"v9.7.111/3/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
Prettier Plugin
prettier-plugin-intlayer puts the keys of your translations in a fixed order every time Prettier formats a file. Diffs stay small, merge conflicts get rarer and a missing locale is easy to spot.
Copy the code to the clipboard
Installation
Copy the code to the clipboard
Requires Prettier 3 or later.
If your project already uses Prettier, intlayer init prettier installs the plugin and adds it to your config for you.
Usage
Add the plugin to your Prettier config:
Copy the code to the clipboard
To apply it to your content declarations only, use an override:
Copy the code to the clipboard
What gets sorted
t(): locales
The pinned locales come first (en by default). The other locales follow in alphabetical order.
Copy the code to the clipboard
plural(): CLDR order
Categories go from the smallest quantity to the fallback: zero, one, two, few, many, other.
Copy the code to the clipboard
enu(): ascending thresholds
Conditions are sorted by their number, then by operator (<1, <=1, 1, >=1, >1). fallback goes last.
Copy the code to the clipboard
At runtime, the first matching condition wins. The plugin applies the new order only when every quantity still resolves to the same content. When order decides the result, the object is left as written. For example, in { '<1': …, '<=-2.3': … } the '<1' key catches every negative number.
select(): alphabetical
Cases are sorted alphabetically and fallback goes last.
Copy the code to the clipboard
Without a fallback or an other key, the last case is used as the fallback. That case stays last and only the cases before it are sorted.
.content.json files
The serialized form is sorted the same way: { "nodeType": "translation", "translation": { … } }, as well as plural, enumeration and select nodes.
Identical translations
In *.content.* files, a t() whose locales all hold the same string is replaced by that string. A plain string is served to every locale, so the output does not change.
Copy the code to the clipboard
A t() with a single locale, a type argument (t<string>()), a comment or non-string values is kept. Set intlayerCollapseIdenticalTranslations: false to turn it off.
Content keys (opt-in)
With intlayerSortContentKeys: true, the plugin also sorts the keys of the dictionary content alphabetically, at every nesting level. This applies only in *.content.* files.
Copy the code to the clipboard
The sort continues through every helper (t, plural, enu, select, cond, gender, md, insert, nest, file…) to reach the objects inside them. Each helper's own key map keeps its ordering. The keys passed to cond() and gender() are never reordered, because their last key is the fallback. The fields next to content (key, title, locale…) stay as they are.
Options
Open the table in a modal to view all data content clearly
| Option | Default | Description |
|---|---|---|
intlayerPinnedLocales | ["en"] | Locales kept first in t(), in this order. Pass [] to sort every locale. |
intlayerSortContentKeys | false | In *.content.* files, also sort the dictionary content keys and nested objects. |
intlayerCollapseIdenticalTranslations | true | In *.content.* files, replace a t() whose locales all hold the same string by that string. |
What is left untouched
- Objects holding a spread (
...base), a computed key ([key]), a method or a duplicated key. plural()maps with a key that is not a CLDR category.enu()maps whose new order would change the resolved content.- Calls to any other function named like a helper but given a non-object argument.
Comments move with the key they belong to.
Supported parsers
babel, babel-flow, babel-ts, typescript, flow, acorn, espree, meriyah, json, json5 and jsonc. The <script> blocks of Vue, Svelte and Astro files are formatted with these parsers.
Known limitation. Prettier runs a single plugin per parser. If another plugin also replaces the JavaScript/TypeScript parsers (for exampleprettier-plugin-tailwindcss), only the last one listed applies to those files. Scopeprettier-plugin-intlayerto*.content.*files with an override to avoid the conflict.
