Supported File Types (Strings)

.FTL - Fluent (Strings)

File Extensions 

.ftl

API Extension 

fluent

Import 

Yes

Export 

Yes

Plural forms support 

Yes (partial)

Description support 

Yes

Format options 

These options that can be specified when a file is uploaded and/or downloaded. Depending on the upload/download method (API, CLI, Repo sync etc.), they can be specified in query parameters Upload, Download or in the phrase.yml configuration file.

enable_pluralization

Fluent is the localization system developed by Mozilla and uses .ftl ("Fluent Translation List") files. Fluent is designed for natural-sounding translations. A translation references variables, other translations, and CLDR plural categories directly in Fluent syntax, rather than through generic placeholder or plural syntax added to a plain string.

A Fluent file is a list of Messages and Terms. Each is a key = value pair, optionally with multi-line values, variable interpolation, and plural or select expressions.

teacher-label-block-inactive = { $blockName } (Inactive)
teacher-label-block-name = Class Name
teacher-label-block-name-placeholder = Enter class name
teacher-label-block-student-count =
    { $studentCount ->
        [one] { $studentCount } student
       *[other] { $studentCount } students
    }

Format Options

enable_pluralization

  • Type: Boolean

  • Default: true

  • Function: When enabled, a translation whose entire value is a CLDR-shaped select expression is imported as a pluralized key. Such an expression contains at least one standard plural category (zero, one, two, few, many, other), optionally combined with exact-match number literals such as [0]. The plural editor in Phrase shows each category separately. When disabled, select expressions are imported as literal translation content. Disable the option if the plural decomposition does not fit the project workflow.

Key Features

  • Messages

    Messages are the basic translatable unit: key = value. Values can span multiple lines, indented under the key.

  • Terms

    Terms are reusable fragments, such as a product or brand name, that cannot stand alone. A Term is declared with a leading hyphen: -brand-name = Firefox and referenced from a Message as { -brand-name }.

    Phrase imports a Term as a key named -brand-name. The hyphen is kept because a Message key in Fluent cannot start with one.

  • Attributes

    A Message or Term can carry named sub-values, such as the placeholder text of a UI field alongside its label:

    login-input = Predefined value
        .placeholder = nickname

    Phrase imports each Attribute as a separate key named {message-id}.{attribute-id} (or -{term-id}.{attribute-id} for a Term attribute). This follows the dot-grouping convention of other key-value formats in Phrase.

  • Comments

    A comment block (#, ##, or ###) placed directly above a Message or Term, with no blank line in between, is imported as the description of that key.

    A comment separated from the next entry by a blank line, or not followed by an entry, is not imported.

  • Placeables and variables

    Placeables such as { $variable }, { -term }, and function calls like { NUMBER($value) } stay in the translation content as literal Fluent syntax. Translators edit this syntax directly as part of the string, as with ICU plural and select syntax in the .ARB format. Phrase does not convert these into separate placeholder tokens.

Pluralization

A value that consists entirely of a select expression is imported as a pluralized key when its variants look like a real plural. This means at least one CLDR category, with any other variant limited to an exact-match number literal, such as [0] alongside [one] and *[other].

unread-emails =
    { $unreadCount ->
        [one] You have one unread email.
       *[other] You have { $unreadCount } unread emails.
    }

This example is imported as a pluralized key with one and other variants. On export, it returns to the same shape and keeps the original $unreadCount selector variable instead of a generic placeholder name.

The following are imported as literal content, like any other Fluent value, and do not appear in the plural editor:

  • A select expression embedded inside a longer sentence, e.g., Upload { $count } { $count -> [one] file *[other] files }.

  • A select expression with non-CLDR keys. Fluent also uses this syntax for grammatical case or gender selection on a Term (for example, [nominative] and [accusative]), which is not a plural.

Limitations

  • Attributes are mapped to dotted key names (message.attribute). A key that contains a dot but did not come from a Fluent import, for example one converted from another format, may be exported as a Fluent Attribute instead of a standalone Message.

  • Advanced Fluent features, such as Term attributes with parameters and custom functions beyond simple interpolation, are preserved as literal text inside a value. Phrase does not validate or restructure them on import or export.

  • Invalid Fluent syntax fails the import with a syntax error. Phrase does not skip the invalid entry.

Was this article helpful?
★ ★ ★ ★ ★

Sorry about that! In what way was it not helpful?

The article didn’t address my problem.
I couldn’t understand the article.
The feature doesn’t do what I need.
Other reason.

Note that feedback is provided anonymously so we aren't able to reply to questions.
If you'd like to ask a question, submit a request to our Support team.
Thank you for your feedback.