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