fluent.js
repository·main·Indexed 21 days ago
https://github.com/projectfluent/fluent.jsA JavaScript implementation of the Project Fluent localization framework for handling complex natural language requirements like plurals and gender. The project includes several packages: @fluent/bundle for formatting translations, @fluent/dom for DOM-based translation, @fluent/react for React integration, @fluent/langneg for language negotiation, @fluent/syntax for parsing FTL, @fluent/dedent for template literal dedenting, and @fluent/sequence for bundle sequences.
What's inside fluent.js
- Fluent.js is a JavaScript implementation of Project Fluent, a localization framework. It is designed to handle both simple translations and complex natural language concepts such as gender, plurals, and conjugations using the FTL (Fluent Translation List) syntax.
What is fluent-gecko
mainfluent-geckois a distribution of Project Fluent that is specifically compatible with Gecko (the engine used by Mozilla Firefox). It is designed to provide files that are ready for vendoring intomozilla-central.Understand likely subtags in @fluent/langneg
mainThe module includes a minimal list of "likely subtags" data. This allows the negotiation algorithm to find more specific available locales even when a requested locale is too generic.
For example, if a user requests the generic
enlocale, but your application only supportsen-GBanden-US, the likely subtags data helps the negotiator bridge that gap to find a suitable match.How DOMLocalization works for DOM-based translation
mainThe
DOMLocalizationclass is designed for full-fallback ready message formatting within the DOM. It works by identifying localizable elements via thedata-l10n-idattribute.Key workflow:
- Initialize
DOMLocalizationwith a list of FTL resource paths and agenerateBundlesgenerator function. - Call
connectRoot(root)to specify the starting point in the DOM. - Call
translateRoots()to perform the initial translation of the DOM tree. - Use
setAttributes(element, id, args)to update specific elements. This method setsdata-l10n-idanddata-l10n-argson the element, which triggers an internalMutationObserverto automatically translate the element.
import { DOMLocalization } from "@fluent/dom"; const l10n = new DOMLocalization( ["/browser/main.ftl", "/toolkit/menu.ftl"], generateBundles ); l10n.connectRoot(document.documentElement); l10n.translateRoots(); const h1 = document.querySelector("h1"); // Sets `data-l10n-id` and `data-l10n-args` which triggers // the `MutationObserver` from `DOMLocalization` and translates the // element. l10n.setAttributes(h1, "welcome", { user: "Anna" });- Initialize
Configure language negotiation strategies
mainThe
negotiateLanguagesAPI supports three different strategies via thestrategyoption. Choose the one that best fits your application's requirements for how many locales should be returned:filtering(default): Tries to match as many available locales as possible for each requested locale.- Example: If requested
['de-DE', 'fr-FR']and available['de', 'fr'], it returns['de', 'fr'].
- Example: If requested
matching: Looks for the single best matching available locale for each requested locale.- Example: If requested
['de-DE', 'fr-FR']and available['de', 'fr'], it returns['de', 'fr'](but focuses on the best match per request).
- Example: If requested
lookup: Tries to find the single best locale for the entire requested locale list among the available locales.- Example: If requested
['de-DE', 'fr-FR']and available['de-DE', 'fr'], it returns only the single best match, e.g.,['de-DE'].
- Example: If requested
let supported = negotiateLanguages(requested, available, { strategy: "matching", });Understand the FTL (Fluent Translation List) syntax
mainFTL is the file format used for describing translation resources. It allows for simple key-value mappings as well as complex linguistic logic.
Example of a simple FTL entry with a variable:
hello-user = Hello, { $username }!For detailed syntax rules, refer to the Fluent Syntax Guide.
How to use fluent-gecko for mozilla-central vendoring
mainIf you are working with
mozilla-central,fluent-geckocan build the specific files required for integration. The distribution provides:FluentSyntax.jsm: Located inintl/l10n/withinmozilla-central.fluent-react.js: Located indevtools/client/shared/vendor/withinmozilla-central.
Measure performance with the perf tool
mainTo measure the performance impact of changes made to the fluent.js codebase, run the performance test script located in the
perfdirectory../perf/test.jsRun performance tests with test.js
mainUse the
test.jsscript to measure the performance impact of changes to thefluent.jscodebase. The script measures the speed of parsing, compilation, and entity retrieval using a resource file containing approximately 500 entities (imitating a real-world scenario like Firefox OS's settings localization). Execution time is reported in milliseconds (ms).To ensure reliable measurements and avoid JIT (Just-In-Time) compilation bias, the script spawns the target command via
child_process.execfor a large sample of runs. If nocommandis provided, it is automatically determined based on the selected--engine.# Run with default settings ./test.js # Run using a specific engine (node, jsshell, or d8) ./test.js --engine jsshell # Run with a large sample size and show progress ./test.js --sample 1000 --progress # Run a specific custom command ./test.js "~/src/jsshell/js benchmark.jsshell.js"Set up a local development environment for fluent.js
mainTo contribute to or build
fluent.jslocally, follow these steps:- Prerequisites: Ensure you have Node.js 20.19 or newer installed. Older versions are not supported.
- Clone the repository:
git clone https://github.com/projectfluent/fluent.js.git cd fluent.js - Install dependencies: Use npm workspaces to install dependencies for all packages:
npm install - Build and test all packages:
Run the following command to clean, build, lint, test, and generate documentation for all workspaces:
npm run dist
Alternatively, you can build a specific package by navigating to its directory and running:
npm run buildgit clone https://github.com/projectfluent/fluent.js.git cd fluent.js npm install npm run distUse @fluent/bundle to format translations
mainTo format translations, use the
FluentBundleconstructor to create a bundle for a specific locale, add aFluentResourcecontaining FTL (Fluent Translation Language) content, and then usegetMessageandformatPatternto resolve messages with provided arguments.import { FluentBundle, FluentResource } from "@fluent/bundle"; // 1. Define your FTL resource let resource = new FluentResource(` -brand-name = Foo 3000 welcome = Welcome, {$name}, to {-brand-name}! `); // 2. Create a bundle for a specific locale let bundle = new FluentBundle("en-US"); // 3. Add the resource and check for syntax errors let errors = bundle.addResource(resource); if (errors.length) { // Handle syntax errors (errors are per-message) } // 4. Retrieve and format a message let welcome = bundle.getMessage("welcome"); if (welcome.value) { let result = bundle.formatPattern(welcome.value, { name: "Anna" }); // result → "Welcome, Anna, to Foo 3000!" }Install Fluent.js packages
mainFluent.js is modular. You can install specific packages via
npmdepending on your use case. Common packages include:@fluent/bundle: Core bundling functionality.@fluent/dedent: String dedenting utility.@fluent/dom: DOM-related utilities.@fluent/langneg: Language negotiation.@fluent/react: React integration.@fluent/sequence: Sequence handling.@fluent/syntax: Syntax parsing and handling.
To install a package, use
npm install <package-name>.npm install @fluent/react