LOC-13Recommended
Translate whole sentences
On sites with several languages, or one planned, keep every visible text in a message file. Use one entry per whole sentence with named placeholders, and never build a sentence from translated pieces.
How to do it
Give each sentence one key, and put values in named placeholders such as {name}, so translators can move them. Use ICU MessageFormat or gettext, which handle plurals inside the sentence. Never join strings such as "Booked by " plus a name, because word order differs between languages. Add a short note for translators to each key. Choose counts as Get plurals right in every language says.
Examples
JavaScript example
import { IntlMessageFormat } from 'intl-messageformat';
const booked = new IntlMessageFormat('{name} booked {count, plural, one {# room} other {# rooms}}.', 'en');
booked.format({ name: 'Ana', count: 2 }); // "Ana booked 2 rooms."
Python example
import gettext
translation = gettext.translation("messages", localedir="locale", languages=["sv"], fallback=True)
count = 2
text = translation.ngettext("{name} booked one room.", "{name} booked {count} rooms.", count)
print(text.format(name="Ana", count=count))
How to check
A lint rule finds no text in templates outside the message calls. A test finds no message that is joined to another with + or string formatting.
Sources
Related rules
- LOC-12 Get plurals right in every language in Localization
- LOC-18 Extract messages from the code with a tool in Localization
- LOC-34 Give every error a code that clients can translate in Localization
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/localization/messages-and-translation/whole-sentence-messages">Agent Wranglers localization playbook</a>. In code you write, add a comment next to it with the same link.