Description
Feature Proposal: Migrate to Fluent for Flexible, Grammatically Correct Localization
Background
Our users want to change core UI terms (for example, calling “Document” a “Note” instead) and have the entire UI grammar follow automatically. In Ticket #602 we proposed making key nouns customizable. Currently our system uses static strings (often with English text as the key), but that cannot adjust articles, adjectives, etc. when the noun’s gender or number changes.
The Problem: Grammatical Agreement
Simple find‑and‑replace of a noun breaks grammar. For example, in French:
- “Le document est important.” (masculine)
- → “La note est importante.” (feminine)
Not only does the noun change, but the article (“Le”→“La”) and adjective ending (“important”→“importante”) must change as well. A robust solution must let translators express these rules so everything updates correctly.
Fluent (Localization System)
Mozilla’s Fluent is a localization framework explicitly built for this kind of flexibility. In Fluent, each message has an ID and can refer to terms (starting with -
) that carry grammatical attributes. A term might define a .gender
, and the message can use a select
expression to vary the output based on that attribute 1.
Example:
# glossary.ftl (default)
-app-document-term = document
.gender = "masculine"
# fr/main.ftl
the-document-is-important =
{ -app-document-term.gender ->
[masculine] Le { -app-document-term } est important.
[feminine] La { -app-document-term } est importante.
*[other] Le { -app-document-term } est important.
}
-
If
-app-document-term = document
with.gender = "masculine"
, the sentence is:
Le document est important.
-
If an admin overrides the term:
-app-document-term = note (.gender = "feminine")
,
→La note est importante.
This works without changing the app logic or the main translation files. Only the term definition changes.
Key Strategy: Message IDs, not English Sentences
In our current system, we often use English strings as translation keys. Fluent, however, separates message ID from source value. This means we’ll define messages like:
the-document-is-important = The document is important.
And translators will work with that. This avoids key fragility and supports context-specific grammar 2.
Crowdin Integration and Developer Effort
✅ Crowdin Supports Fluent
Crowdin supports .ftl
files 34. Translators will see Fluent syntax, including select expressions and variable placeholders. Crowdin doesn’t currently provide a visual editor for select expressions, but supports comments, screenshots, and glossary terms to aid translators 5.
Glossary terms in Crowdin can include attributes such as gender or part of speech 6, which aligns well with Fluent’s grammatical model.
💻 Developer Work
We will:
- Add the i18next-fluent module https://github.com/i18next/i18next-fluent
- Define terms like
-app-document-term
in each language’s glossary.ftl
Interchangable terms in translations / Glossary Translations / Branding #602 - Migrate the translations to .ftl files.
- Use the glossary-terms in the migrated .ftl files Interchangable terms in translations / Glossary Translations / Branding #602
Fluent lets us write logic-free UI code. No more inline grammar rules or if-statements in code—only in the .ftl
files.
🔄 Migration Plan
We can convert existing translation files using Mozilla’s fluent.migrate
tools 7. These help automate the transformation of old keys into Fluent messages.
Crowdin will manage translation for .ftl
files post-migration.
Benefits
- ✅ Flexible Terminology: Admins can customize a term like “document” → “note”; grammar adjusts automatically.
- ✅ Stable App Logic: Application code stays unchanged.
- ✅ Grammatical Correctness: All grammar handled in
.ftl
, not in code. - ✅ Crowdin Compatible:
.ftl
files are supported; translators can work in existing workflows.
Considerations
- 🧠 Fluent has a learning curve. Developers and translators must learn how to use message IDs, terms, and attributes.
- 📦 We need a one-time migration of all translation content into
.ftl
. - 🔧 Crowdin lacks full visual support for Fluent’s advanced grammar logic; translators need guidance and good context.
Conclusion
Fluent allows us to decouple application logic from grammar and terminology. It supports user-defined term overrides that trigger automatic grammatical updates, making it ideal for a system that needs deep UI customization.
Migration requires effort but gives us long-term maintainability, correctness, and customization power.
References
Footnotes
-
Mozilla Fluent – Attributes and Selectors: https://projectfluent.org/fluent/guide/terms.html ↩
-
Mozilla on Best Practices for Message IDs: https://github.com/projectfluent/fluent/wiki/Guidelines-for-Message-Identifiers ↩
-
Crowdin – Fluent (.ftl) Support Announcement (2021): https://crowdin.com/blog/2021/09/02/what-is-new-at-crowdin-august-2021-roundup#new-file-format-added ↩
-
Crowdin Docs – Supported Formats: https://store.crowdin.com/ftl ↩
-
Crowdin Glossary and Context Features: https://support.crowdin.com/glossary/ ↩
-
Translate Glossary App (Crowdin Store): https://crowdin.com/store/translate-glossary ↩
-
Fluent Migration Tools (GitHub): https://github.com/mozilla/fluent-migrate ↩
Metadata
Metadata
Assignees
Labels
Type
Projects
Status