### Declarative HTML Example Source: https://github.com/projectfluent/fluent/wiki/Integrating-Fluent-—-Overview An example of declarative UI markup using HTML. ```html

Hello World

``` -------------------------------- ### Basic Multiline Text Examples Source: https://github.com/projectfluent/fluent/blob/main/guide/multiline.md Demonstrates single-line, multi-line, and block-style multiline text formatting. ```fluent single = Text can be written in a single line. multi = Text can also span multiple lines as long as each new line is indented by at least one space. block = Sometimes it's more readable to format multiline text as a "block", which means starting it on a new line. All lines must be indented by at least one space. ``` -------------------------------- ### Build and Deploy Documentation Source: https://github.com/projectfluent/fluent/wiki/Publishing-Fluent-Syntax-Spec Build the generated documentation and deploy it. Ensure you have run `npm run build:guide` before deploying. ```bash $ npm run build:guide $ npm run deploy ``` -------------------------------- ### Fluent Localization Resource Example Source: https://github.com/projectfluent/fluent/wiki/Integrating-Fluent-—-Overview A Fluent resource file defining localization strings, including attributes for a button. ```properties hello-world = Hello World click-button = Click me .title = Click to open a menu .accesskey = C ``` -------------------------------- ### Imperative JavaScript Example Source: https://github.com/projectfluent/fluent/wiki/Integrating-Fluent-—-Overview An example of imperative UI markup using JavaScript console logging. ```javascript console.log("Hello World"); console.log("You have 5 unread messages."); ``` -------------------------------- ### Fluent Low-Level API Example Source: https://github.com/projectfluent/fluent/wiki/Integrating-Fluent-—-Overview Demonstrates the core Fluent API for message retrieval and formatting in JavaScript. Requires a FluentResource and FluentBundle. ```javascript let resource = new FluentResource(` hello-world = Hello World unread-messages = You have { $unreadCount -> [one] unread message *[other] unread messages }`); let bundle = new FluentBundle(["en"]); bundle.addResource(resource); let helloWorld = bundle.getMessage("hello-world"); console.log(bundle.formatPattern(helloWorld.value)); let unreadMessages = bundle.getMessage("unread-messages"); console.log(bundle.formatPattern(unreadMessages.value, {unreadCount: 5})); ``` -------------------------------- ### Fluent High-Level API Example Source: https://github.com/projectfluent/fluent/wiki/Integrating-Fluent-—-Overview Illustrates the high-level Fluent API using a Localization class for asynchronous resource loading and language negotiation. Assumes existence of `negotiateLanguages`, `loadFie`, and `AVAILABLE_LANGS`. ```javascript const AVAILABLE_LANGS = ["de", "en", "fr"]; async function * generateBundles(resourceIds) { let languages = negotiateLanguages(navigator.languages, AVAILABLE_LANGS); for (const lang of languages) { let bundle = new FluentBundle(lang); for (let resourceId of resourceIds) { let source = await loadFile(resourceId); let resource = new FluentResource(source); bundle.addResource(resource); } yield bundle; } } let l10n = new Localization([ '/browser/main.ftl', ], generateBundles); let msg = await l10n.formatValue('hello-world'); console.log(msg); ``` -------------------------------- ### Mixed Control Formatting Example Source: https://github.com/projectfluent/fluent/wiki/Fluent-and-ICU-MessageFormat Illustrates a scenario where the developer sets initial formatting (currency) and the localizer can override specific aspects (currency display, grouping). This provides a balance of control. ```javascript // main.js: data = { amount: Fluent.NumberArgument(value, { currency: "USD" }) } ``` ```ftl amount-owed = You owe { NUMBER($amount, currencyDisplay: "code", useGrouping: "false") } ``` -------------------------------- ### Developer Driven Formatting Example Source: https://github.com/projectfluent/fluent/wiki/Fluent-and-ICU-MessageFormat Shows how a developer can set specific formatting options, like currency, which the localizer cannot override. The JavaScript code prepares the number with currency, and the Fluent file uses it directly. ```javascript // main.js: data = { amount: Fluent.NumberArgument(value, { currency: "USD" }) } ``` ```ftl amount-owed = You owe { $amount } ``` -------------------------------- ### Localizer Driven Formatting Example Source: https://github.com/projectfluent/fluent/wiki/Fluent-and-ICU-MessageFormat Demonstrates how a localizer can control date formatting by specifying the style. The JavaScript code provides the date object, and the Fluent file defines the formatting. ```javascript // main.js: data = { date: new Date(0) } ``` ```ftl today = Today is { DATETIME($date, style: "long") } ``` -------------------------------- ### HTML Data Binding for Localization Source: https://github.com/projectfluent/fluent/wiki/Integrating-Fluent-—-Overview Example of using `data-l10n-id` attribute in HTML to bind UI elements to Fluent localization strings. ```html

``` -------------------------------- ### Explicit Number Formatting Source: https://github.com/projectfluent/fluent/blob/main/guide/variables.md Illustrates using the NUMBER built-in function for explicit control over number formatting. This example limits the fraction digits for the duration. ```fluent # $duration (Number) - The duration in seconds. time-elapsed = Time elapsed: { NUMBER($duration, maximumFractionDigits: 0) }s. ``` -------------------------------- ### Fluent Multiline / DOM Fragment Example Source: https://github.com/projectfluent/fluent/wiki/Fluent-and-ICU-MessageFormat Demonstrates Fluent's first-class support for multiline messages, which is particularly useful for localizing DOM fragments. This avoids the complex escaping required by MessageFormat. ```plaintext download-block = You can download { $brand-name } by clicking on the Download button or read the release notes to learn more. ``` -------------------------------- ### Handling Selectors with Default Variant Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers This example shows a selector with a default variant. Be cautious, as a problematic default variant can lead to data loss if the selector's value is unexpected. ```fluent item-action = Are you sure you want to { $action -> *[add] add [del] remove } this item? ``` -------------------------------- ### Defining Attributes for a Message Source: https://github.com/projectfluent/fluent/blob/main/guide/attributes.md This example shows how to define attributes like placeholder, aria-label, and title for a login input message. Attributes are appended to the message identifier using a dot notation. ```fluent login-input = Predefined value .placeholder = email@example.com .aria-label = Login input value .title = Type your login email ``` -------------------------------- ### Implicit Number Formatting Source: https://github.com/projectfluent/fluent/blob/main/guide/variables.md Shows how numbers are automatically formatted based on the locale's rules. The example illustrates how a duration in seconds is displayed with locale-specific separators. ```fluent # $duration (Number) - The duration in seconds. time-elapsed = Time elapsed: { $duration }s. ``` -------------------------------- ### Logging Parser Success with map(print) Source: https://github.com/projectfluent/fluent/wiki/Debugging-the-Reference-Parser Use `map(print)` to log the `Success` output of any parser. This example shows inspecting the parsing result after each step in an `identifier` parser. ```javascript let identifier = sequence( charset("a-zA-Z"), repeat( charset("a-zA-Z0-9_-"))) .map(print) .map(flatten(1)) .map(print) .map(join) .map(print); ``` -------------------------------- ### Fluent Compound Message Example Source: https://github.com/projectfluent/fluent/wiki/Fluent-and-ICU-MessageFormat Demonstrates how Fluent supports compound messages, allowing multiple related translations to be grouped under a single message ID. This is useful for complex UI widgets. ```javascript // fluent.js: // This is a comment applicable to the whole compound message confirm = Do you want to delete all your emails? .ok = Yes .cancel = No // {React|Web}Component: ``` -------------------------------- ### Junk AST Node with ParseError Annotation Source: https://github.com/projectfluent/fluent/blob/main/spec/errors.md The `annotations` field of an `Entry` instance collects parsing errors. This `Junk` node shows an example with a `ParseError` annotation. ```json { "type": "Junk", "annotations": [ { "message": "Missing field", "name": "ParseError", "pos": 85 } ], "content": "hello-world Hello, world!\n\n", "span": { "from": 73, "to": 100 } } ``` -------------------------------- ### Basic Term Definition Source: https://github.com/projectfluent/fluent/blob/main/guide/terms.md Defines simple terms that can be referenced in other messages. Identifiers start with a dash. ```fluent -brand-name = Firefox about = About { -brand-name }. update-successful = { -brand-name } has been updated. ``` -------------------------------- ### Implicit NUMBER formatting Source: https://github.com/projectfluent/fluent/blob/main/guide/functions.md FTL implicitly calls NUMBER for numeric variables in placeables. This example shows the explicit call for comparison. ```ftl emails = Number of unread emails { $unreadEmails } ``` ```ftl emails2 = Number of unread emails { NUMBER($unreadEmails) } ``` -------------------------------- ### Handling Pluralization with a Default Variant Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers This example demonstrates correct pluralization handling where the default variant covers all cases, including zero, one, and other quantities. The `[0]` variant adds specific flavor. ```fluent new-notifications = { $num -> [0] No new notifications. [one] New notification. *[other] { $num } new notifications. } ``` -------------------------------- ### Incorrect Handling of Zero Case in Pluralization Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers This example is incorrect because the `[0]` variant serves a distinct UI purpose and should be a separate message, not part of the pluralization selector. ```fluent items-selected = { $num -> [0] Select items. [one] One item selected. *[other] { $num } items selected. } ``` -------------------------------- ### Implicit DATETIME formatting Source: https://github.com/projectfluent/fluent/blob/main/guide/functions.md FTL implicitly calls DATETIME for date variables in placeables. This example shows the explicit call for comparison. ```ftl log-time = Entry time: { $date } ``` ```ftl log-time2 = Entry time: { DATETIME($date) } ``` -------------------------------- ### Select Expression with Number Selector and Formatting Source: https://github.com/projectfluent/fluent/blob/main/guide/selectors.md Use number selectors with formatting options to match CLDR plural categories. This example formats a score with one decimal place. ```ftl your-score = { NUMBER($score, minimumFractionDigits: 1) -> [0.0] You scored zero points. What happened? *[other] You scored { NUMBER($score, minimumFractionDigits: 1) } points. } ``` -------------------------------- ### Select Expression with Ordinal Plurals Source: https://github.com/projectfluent/fluent/blob/main/guide/selectors.md Use the 'type: "ordinal"' option with NUMBER to select based on ordinal plural categories. This example handles first, second, third, and other ranks. ```ftl your-rank = { NUMBER($pos, type: "ordinal") -> [1] You finished first! [one] You finished {$pos}st [two] You finished {$pos}nd [few] You finished {$pos}rd *[other] You finished {$pos}th } ``` -------------------------------- ### Corrected Pluralization with Separate Zero Case Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers This corrected example separates the 'Select items' case into its own message and uses a default variant for 'one' and 'other' plural forms, ensuring the default works for all remaining values. ```fluent # ✅ Separate messages which serve different purposes. items-select = Select items # ✅ The default variant works for all values of the selector. items-selected = { $num -> [one] One item selected. *[other] { $num } items selected. } ``` -------------------------------- ### Date Formatting with Arguments in Fluent Source: https://github.com/projectfluent/fluent/blob/main/guide/builtins.md Shows how to format a datetime value using the DATETIME function with specific arguments for day and month presentation. ```fluent last-notice = Last checked: { DATETIME($lastChecked, day: "numeric", month: "long") }. ``` -------------------------------- ### Basic and Number Formatting in Fluent Source: https://github.com/projectfluent/fluent/blob/main/guide/builtins.md Demonstrates basic string interpolation and explicit number formatting using Fluent's built-in capabilities. ```fluent emails = You have { $unreadEmails } unread emails. emails2 = You have { NUMBER($unreadEmails) } unread emails. ``` -------------------------------- ### Handling Leading Spaces and Lines Source: https://github.com/projectfluent/fluent/blob/main/guide/multiline.md Shows how leading spaces and blank lines before the actual text are ignored. ```fluent leading-spaces = This message's value starts with the word "This". leading-lines = This message's value starts with the word "This". The blank lines under the identifier are ignored. ``` -------------------------------- ### Importing and using the parse function Source: https://github.com/projectfluent/fluent/blob/main/spec/errors.md Import the `parse` function from `fluent-syntax` and use it to parse a source string into a `Resource` node. ```javascript import { parse } from 'fluent-syntax'; const resource = parse(source_string); ``` -------------------------------- ### Basic Variable Interpolation Source: https://github.com/projectfluent/fluent/blob/main/guide/variables.md Demonstrates how to use variables with the $variable-name syntax for dynamic content. Variables are provided by the app and can be interpolated into translations. ```fluent welcome = Welcome, { $user }! unread-emails = { $user } has { $email-count } unread emails. ``` -------------------------------- ### Helper functions for position calculation Source: https://github.com/projectfluent/fluent/blob/main/spec/errors.md The `fluent-syntax` package provides `lineOffset` and `columnOffset` helpers to calculate 0-based offsets from a source string and position. ```javascript // lineOffset(source, pos) // columnOffset(source, pos) ``` -------------------------------- ### Simple Hello World Message Source: https://github.com/projectfluent/fluent/blob/main/guide/hello.md This is the most basic Fluent message format, consisting of an identifier and a simple text value. It's used for straightforward string localization. ```fluent hello = Hello, world! ``` -------------------------------- ### Parsing FTL files with bin/parse.mjs CLI Source: https://github.com/projectfluent/fluent/wiki/Debugging-the-Reference-Parser The `bin/parse.mjs` CLI utility parses FTL files and prints the resulting AST. It can read from files or standard input. ```bash node --experimental-modules bin/parse.mjs path/to/file.ftl ``` ```bash echo "x = X" | node --experimental-modules bin/parse.mjs path/to/file.ftl - ``` ```bash node --experimental-modules bin/parse.mjs <(echo "x = X") ``` -------------------------------- ### Use Direct Message References for UI Logic in Fluent Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers Let the `l10n` library handle setting element values directly. This ensures re-translation on language changes and simplifies code by avoiding manual formatting. ```javascript // ✅ Let `l10n` handle setting the value of `element`. This also ensures // that the element is re-translated when the user's language changes. l10n.setAttributes(element, `reacted-with-${notification.type}`); ``` -------------------------------- ### MessageFormat and Fluent Syntax Comparison Source: https://github.com/projectfluent/fluent/wiki/MessageFormat-vs-Fluent-Syntax Compares the syntax of MessageFormat and Fluent for handling pluralization and date formatting. Fluent uses sigils like '$' for variables and all-caps for function names for better readability. ```plaintext // MessageFormat: {unreadEmails, plural, one {You have one unread email from {date, datetime, short }.} other {You have {unreadEmails} unread emails.} } // Fluent: emails = { $unreadEmails -> [one] You have one unread email from { DATETIME($date, style: "short") }. *[other] You have { $unreadEmails } unread emails. } ``` -------------------------------- ### Test and Validate Fluent Parser Source: https://github.com/projectfluent/fluent/blob/main/README.md Commands to test, lint, and generate artifacts for the Fluent parser during development. ```bash npm test npm run lint npm run generate:ebnf npm run generate:fixtures npm run build:guide npm run bench ``` -------------------------------- ### Multiline Dedentation with First Line Unindented Source: https://github.com/projectfluent/fluent/blob/main/guide/multiline.md Demonstrates dedentation when the first line is not indented relative to subsequent lines, preserving initial spaces. ```fluent multiline2 = ████··This message starts with 2 spaces on the first ████first line of its value. The first 4 spaces of indent ████are removed from all lines. ``` -------------------------------- ### Referencing a Simple Message Source: https://github.com/projectfluent/fluent/blob/main/guide/references.md Reference the 'menu-save' message within the 'help-menu-save' message to ensure consistent text. ```fluent menu-save = Save help-menu-save = Click { menu-save } to save the file. ``` -------------------------------- ### Basic Select Expression with String Selector Source: https://github.com/projectfluent/fluent/blob/main/guide/selectors.md Use select expressions to choose between translation variants based on a string variable. The '*' indicates the default variant. ```ftl emails = { $unreadEmails -> [one] You have one unread email. *[other] You have { $unreadEmails } unread emails. } ``` -------------------------------- ### Developer pre-formatting with FluentDateTime Source: https://github.com/projectfluent/fluent/blob/main/guide/functions.md Developers can pre-format variables using FluentDateTime with specific options. ```javascript ctx.format('today', { day: new FluentDateTime(new Date(), { weekday: 'long' }) }) ``` -------------------------------- ### Debugging Parser Failures with bimap(print, print) Source: https://github.com/projectfluent/fluent/wiki/Debugging-the-Reference-Parser Use `bimap(print, print)` to see why a parse fails. The first function maps the `Success` value, and the second maps the `Failure` value. This is useful for diving deeper into unexpected parse results. ```javascript let identifier = sequence( charset("a-zA-Z"), repeat( charset("a-zA-Z0-9_-"))) .map(flatten(1)) .map(join) .bimap(print, print); ``` -------------------------------- ### Complex Message Formatting in Fluent Source: https://github.com/projectfluent/fluent/wiki/MessageFormat-vs-Fluent-Syntax Demonstrates a complex message structure in Fluent using nested pluralization, function calls like PLURAL, TAKE, DROP, LEN, and string manipulation. This showcases Fluent's power for intricate localization needs. ```plaintext liked-photo = { PLURAL($people) -> [1] { $people } lubi [2] { $people } lubią [3] { TAKE(2, $people), "jedna inna osoba" } lubią *[other] { TAKE(2, $people), "{ PLURAL(DROP(2, $people)) -> [1] jedna inna osoba lubią [few] { LEN(DROP(2, $people)) } inne osoby lubią *[many] { LEN(DROP(2, $people)) } innych osób lubi }" } } Twoje zdjęcie. ``` -------------------------------- ### Multiline Dedentation with Common Indent Source: https://github.com/projectfluent/fluent/blob/main/guide/multiline.md Explains and visualizes how common leading whitespace is removed from all lines in a multiline pattern. ```fluent multiline1 = This message has 4 spaces of indent on the second line of its value. ``` ```fluent # █ denotes the indent common to all lines (removed from the value). # · denotes the indent preserved in the final value. multiline1 = ████This message has 4 spaces of indent ████····on the second line of its value. ``` -------------------------------- ### Parameterized Term with Select Expression Source: https://github.com/projectfluent/fluent/blob/main/guide/terms.md Shows how to define multiple variants of a term value using select expressions, which can correspond to grammatical cases or other properties. ```fluent -brand-name = { $case -> *[nominative] Firefox [locative] Firefoksie } # "About Firefox." about = Informacje o { -brand-name(case: "locative") }. ``` -------------------------------- ### Multiline Dedentation with First Line on Same Line Source: https://github.com/projectfluent/fluent/blob/main/guide/multiline.md Shows how the first line, when on the same line as the identifier, is not considered indented and its leading spaces are ignored. ```fluent multiline3 = This message has 4 spaces of indent ████····on the second line of its value. The first ████line is not considered indented at all. # Same value as multiline3 above. multiline4 = This message has 4 spaces of indent ████····on the second line of its value. The first ████line is not considered indented at all. ``` -------------------------------- ### Resource AST Node Structure Source: https://github.com/projectfluent/fluent/blob/main/spec/errors.md The `Resource` AST node includes a `source` field in its constructor, in addition to `body` and `comment`. ```javascript export class Resource extends Node { constructor(body = [], comment = null, source = '') { super(); this.type = 'Resource'; this.body = body; this.comment = comment; this.source = source; } } ``` -------------------------------- ### Parameterized Term with Variable Source: https://github.com/projectfluent/fluent/blob/main/guide/terms.md Demonstrates passing variables into a term. The term receives data for variables from the messages that use it. ```fluent # A contrived example to demonstrate how variables # can be passed to terms. -https = https://{ $host } visit = Visit { -https(host: "example.com") } for more information. ``` -------------------------------- ### Call DATETIME function with options Source: https://github.com/projectfluent/fluent/blob/main/guide/functions.md Use the DATETIME function to format a date with long month, numeric year, and numeric day. ```ftl today-is = Today is { DATETIME($date, month: "long", year: "numeric", day: "numeric") } ``` -------------------------------- ### Call DATETIME function Source: https://github.com/projectfluent/fluent/blob/main/guide/functions.md Use the DATETIME function to format a date within a message. ```ftl today-is = Today is { DATETIME($date) } ``` -------------------------------- ### Select expression with implicit NUMBER Source: https://github.com/projectfluent/fluent/blob/main/guide/functions.md Demonstrates using a number in a select expression, which implicitly uses the NUMBER function for matching. ```ftl liked-count = { $num -> [0] No likes yet. [one] One person liked your message *[other] { $num } people liked your message } ``` -------------------------------- ### Improve Grep-ability with Message References in Fluent Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers Use a map of message identifiers in code for better grep-ability, making it easier to find and manage message references. This approach simplifies refactoring and message removal. ```javascript // ✅ You can now run `grep` to find references to these messages. // This is super useful when the identifier needs to change or when // you want to remove this message altogether. let messages = { THUMBS_UP: "reacted-with-thumbs-up", SMILEY_FACE: "reacted-with-smiley-face", }; l10n.setAttributes(element, messages[notification.type]); ``` -------------------------------- ### Commit Changes for Release Source: https://github.com/projectfluent/fluent/wiki/Publishing-Fluent-Syntax-Spec Commit the changes with a message indicating the new version number. ```bash $ git commit -m "Fluent Syntax X.Y.Z" ``` -------------------------------- ### Preserving Blank Lines Within Text Source: https://github.com/projectfluent/fluent/blob/main/guide/multiline.md Illustrates how blank lines inside multiline text are preserved if they are positioned between other text lines. ```fluent blank-lines = The blank line above this line is ignored. This is a second line of the value. The blank line above this line is preserved. ``` -------------------------------- ### Call NUMBER function with options Source: https://github.com/projectfluent/fluent/blob/main/guide/functions.md Use the NUMBER function to format a number with specific fraction digit settings. ```ftl dpi-ratio = Your DPI ratio is { NUMBER($ratio, minimumFractionDigits: 2) } ``` -------------------------------- ### Parameterized Term with Default Variant Source: https://github.com/projectfluent/fluent/blob/main/guide/terms.md Illustrates how the default variant of a term is used when no parameters are passed or the term is referenced without parentheses. ```fluent -brand-name = { $case -> *[nominative] Firefox [locative] Firefoksie } # "Firefox has been successfully updated." update-successful = { -brand-name } został pomyślnie zaktualizowany. ``` -------------------------------- ### Avoid Imperative Formatting in Fluent Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers Avoid using imperative APIs like `formatValue` for simple text content. Prefer declarative APIs like `setAttributes` for better integration and automatic re-translation. ```javascript // ❌ Avoid the imperative APIs. let value = await l10n.formatValue("message-id"); element.textContent = value; ``` ```javascript // ✅ Declarative APIs are 👌. l10n.setAttributes(element, "message-id"); ``` -------------------------------- ### Fluent Multi-variant Message without Selector Source: https://github.com/projectfluent/fluent/wiki/Fluent-and-ICU-MessageFormat Illustrates a Fluent message with multiple variants but no explicit selector. A variant can be referenced from another message by specifying its name. ```javascript brand-name = { $case -> *[nominative] Firefox [genitive] Firefoksa [dative] Firefoxu [accusative] Firefox [locative] Firefoxu [instrumental] Firefoxom } hello = Witaj w { brand-name(case: "dative") } ``` -------------------------------- ### React Component with Localized Content Source: https://github.com/projectfluent/fluent/wiki/Integrating-Fluent-—-Overview This snippet demonstrates how to use the Localized component from @fluent/react to wrap UI elements with localized content. It shows a basic React functional component that renders a localized heading. ```jsx export function App() { return (

Hello, world!

); } ``` -------------------------------- ### Select expression with explicit NUMBER Source: https://github.com/projectfluent/fluent/blob/main/guide/functions.md Demonstrates using a number in a select expression with an explicit NUMBER function call to pass formatting options for plural category matching. ```ftl liked-count2 = { NUMBER($num) -> [0] No likes yet. [one] One person liked your message *[other] { $num } people liked your message } ``` -------------------------------- ### Fluent Multi-variant Message with Selector Source: https://github.com/projectfluent/fluent/wiki/Fluent-and-ICU-MessageFormat Shows how Fluent's SelectExpression allows branching message values based on a selector, such as gender. The asterisk indicates the default variant. ```javascript portfolio-cta = { $gender -> [male] Take a look at his portfolio [female] Take a look at her portfolio *[neuter] Take a look at their portfolio } ``` -------------------------------- ### Referencing a Term for Branding Source: https://github.com/projectfluent/fluent/blob/main/guide/references.md Use a term (prefixed with '-') like '-brand-name' to reference branding elements in other messages, facilitating easy updates. ```fluent -brand-name = Firefox installing = Installing { -brand-name }. ``` -------------------------------- ### File-Level Triple-Hash Comments Source: https://github.com/projectfluent/fluent/blob/main/guide/comments.md Utilize triple-hash comments for standalone file-level information, providing context or purpose for the entire localization resource. ```properties ### Localization for Server-side strings of Firefox Screenshots ``` -------------------------------- ### Separate Messages for All Cases Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers Using separate messages for each case ensures that all locales can provide translations for every required scenario, improving translation verification. ```properties # ✅ Separate message mean that tools can easily verify that all locales # have translated all possible cases. item-add = Are you sure you want to add this item? item-del = Are you sure you want to remove this item? ``` -------------------------------- ### Interpolate a Variable Source: https://github.com/projectfluent/fluent/blob/main/guide/placeables.md Use placeables to insert external string variables into translations. The variable's value is provided at runtime. ```fluent remove-bookmark = Really remove { $title }? ``` -------------------------------- ### Avoid Formatting Translation Arguments in Code Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers Avoid retrieving a translation to use as an argument for another translation. This is a code smell. Instead, let the Fluent library handle message composition directly. ```javascript // ❌ Retrieving a translation in order to pass it into another // translation as an argument is a code smell. let reaction_type = notification.type === "THUMBS_UP" ? l10n.formatValue("reaction-thumbs-up") : l10n.formatValue("reaction-smiley-face"); l10n.setAttributes(element, "reacted-with", {reaction_type}); ``` -------------------------------- ### Insert Literal Curly Braces Source: https://github.com/projectfluent/fluent/blob/main/guide/placeables.md Insert literal curly braces into text by quoting them within placeables. This is necessary because curly braces are used as delimiters. ```fluent opening-brace = This message features an opening curly brace: {"{"}. closing-brace = This message features a closing curly brace: {"}"}. ``` -------------------------------- ### Avoid UI-Specific Variants in Fluent Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers Do not use variants for UI logic branching (e.g., button labels like 'THUMBS_UP' or 'SMILEY_FACE'). Instead, use separate messages and select the appropriate one in the code. ```properties # ❌ The variants here are UI-specific. reacted-with = { $user_name } has reacted with { $reaction_type -> *[THUMBS_UP] a thumbs up [SMILEY_FACE] a smiley face }. ``` -------------------------------- ### Group-Level Double-Hash Comments Source: https://github.com/projectfluent/fluent/blob/main/guide/comments.md Employ double-hash comments to create standalone group headers, organizing related messages within a file. ```properties ## Global phrases shared across pages ``` ```properties ## Creating page ``` -------------------------------- ### Use Language-Specific Variants in Fluent Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers Use select expressions and variants only when required by language grammar or style, such as for gendered pronouns. The default variant should make sense for all selector values. ```properties # ✅ The `his`, `her`, `their` variants are language-specific. # The default variant works for all values of the selector. shared-schedule = { $other_user_name } has shared { $other_user_gender -> [male] his [female] her *[other] their } schedule with you. ``` -------------------------------- ### Avoid Splitting Messages in Fluent Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers Avoid splitting common translation phrases into separate messages that are then combined in code. This makes it harder for localizers to understand context. Instead, repeat common phrases or use direct message references. ```properties # ❌ Avoid splitting messages. reaction-thumbs-up = a thumbs up reaction-smiley-face = a smiley face reacted-with = { $user_name } has reacted with { $reaction_type }. ``` -------------------------------- ### Adding Fluent Messages with Escaped Backslashes in JavaScript Source: https://github.com/projectfluent/fluent/blob/main/guide/special.md Illustrates how to add Fluent messages containing Unicode escape sequences to a bundle programmatically in JavaScript, requiring double backslashes for escaping. ```javascript let bundle = new FluentBundle("en"); bundle.addMessages(` privacy-label = Privacy{\"\\u00A0\"}Policy `); ``` -------------------------------- ### Message AST Node with Span Source: https://github.com/projectfluent/fluent/blob/main/spec/errors.md An `Entry` instance, such as this `Message` node, now includes a `span` field indicating its position in the source. ```json { "type": "Message", "annotations": [], "id": { "type": "Identifier", "name": "hello-world" }, "value": { "type": "Pattern", "elements": [ { "type": "StringExpression", "value": "Hello, world!" } ], "quoted": false }, "attributes": null, "comment": null, "span": { "from": 44, "to": 71 } } ``` -------------------------------- ### Use Redundant Messages for UI Logic in Fluent Source: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers Prefer redundancy by repeating common parts of translations in multiple messages for better localizer context. This also simplifies code by allowing direct message setting. ```properties # ✅ Redundancy helps localizers understand each message in full. reacted-with-thumbs-up = { $user_name } has reacted with a thumbs up. reacted-with-smiley-face = { $user_name } has reacted with a smiley face. ``` -------------------------------- ### Quoted Text for Leading Punctuation Source: https://github.com/projectfluent/fluent/blob/main/guide/special.md Use quoted text for literal punctuation marks like brackets when they appear at the beginning of a new line to avoid them being misinterpreted as syntax. ```fluent leading-bracket = This message has an opening square bracket at the beginning of the third line: {"["}. ``` -------------------------------- ### Standalone and Message-Bound Single-Hash Comments Source: https://github.com/projectfluent/fluent/blob/main/guide/comments.md Use single-hash comments for standalone notes or to document specific messages. Comments directly above a message are associated with it. ```properties # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/ ### Localization for Server-side strings of Firefox Screenshots ## Global phrases shared across pages my-shots = My Shots home-link = Home screenshots-description = Screenshots made simple. Take, save, and share screenshots without leaving Firefox. ## Creating page # Note: { $title } is a placeholder for the title of the web page # captured in the screenshot. The default, for pages without titles, is # creating-page-title-default. creating-page-title = Creating { $title } creating-page-title-default = page creating-page-wait-message = Saving your shot… ``` -------------------------------- ### Localizer overriding DATETIME parameters Source: https://github.com/projectfluent/fluent/blob/main/guide/functions.md Localizers can override developer-set parameters by explicitly calling DATETIME with different options. ```ftl today = Today is { DATETIME($day, weekday: "short") } ``` -------------------------------- ### Literal Double Quotes using Quoted Text Source: https://github.com/projectfluent/fluent/blob/main/guide/special.md Demonstrates using quoted text for literal double quotes, though using the actual character directly in regular text is preferred for readability. ```fluent # This is OK, but cryptic and hard to read and edit. literal-quote1 = Text in {"\""}double quotes{"\""}. # This is preferred. Just use the actual double quote character. literal-quote2 = Text in "double quotes". ``` -------------------------------- ### Interpolating Text with Placeables Source: https://github.com/projectfluent/fluent/blob/main/guide/text.md Use curly braces to embed external data or other message values within a text pattern. The variable $title is interpolated here. ```fluent # $title (String) - The title of the bookmark to remove. remove-bookmark = Are you sure you want to remove { $title }? ``` -------------------------------- ### Quoted Text for Preserving Blank Space Source: https://github.com/projectfluent/fluent/blob/main/guide/special.md Employ quoted text to ensure leading or multiple spaces are preserved in translations, as regular text often trims such whitespace. ```fluent blank-is-removed = This message starts with no blanks. blank-is-preserved = {" "}This message starts with 4 spaces. ``` -------------------------------- ### Multiline Text Handling Source: https://github.com/projectfluent/fluent/blob/main/guide/text.md Fluent automatically removes common indentation from multiline text. Ensure each new line is indented by at least one space. ```fluent multi = Text can also span multiple lines as long as each new line is indented by at least one space. Because all lines in this message are indented by the same amount, all indentation will be removed from the final value. indents = Indentation common to all indented lines is removed from the final text value. This line has 2 spaces in front of it. ```