Main menu

26 Feb 2025

Changes to ARB file exports

Loco has supported ARB files for some years. This format is a JSON schema primarily for Dart/Flutter localisation.

In recent days we've received reports of compatibility issues with our exported schema. Upon investigating, it's clear that the schema has been updated since the original specification was published, but only recently have Flutter builds started to fail in some circumstances.

We've also been informed of a change in Flutter that generates translations into source code, but the particular methods employed in the SDK are somewhat out of our remit. Our goal is simply to provide full compatibility with ARB files.

This has led to a wider review of our implementation.

Schema changes

An updated schema was published in the google/arb-editor repository, and has now been moved to google/app-resource-bundle.

The ARB schema is not versioned. As far as we can discern, it has received the following changes at some point since 2018:

  • Removal of "source_text" field:
    We've removed it. Specify arb-version=legacy to get it back.

  • Removal of "screen" and "video" fields:
    We never supported these.

  • Extended placeholder formatting properties:
    These are now retained from file imports.

  • Addition of a global @@comment field:
    We've added this as per our standard export headers.

Placeholder type errors

An immediate issue for Flutter users appears to be related to the placeholder "type" field. Build failures can occur if your base (template) strings have a placeholder type that differs from the one in your downloaded translation files.

As of this notice - if Loco hasn't retained a "type" field from an ARB file import, it will infer numeric types in some instances. Otherwise the field will be omitted, which infers "type":"Object".

Tip: Placeholder metadata seems to be required only for the base strings, so this particular problem may be solvable by exporting compact ARB files for translations. See the new parameters below.

Extended formatting parameters

The more recently added placeholder properties are effectively formatting arguments, except they're external to the translation message syntax. This is part of a move by Flutter towards ICU MessageFormat syntax, except that instead of embedding the syntax in the message, it is held as an external part of the JSON schema.

Example from the Flutter docs:

{
  "numberOfDataPoints": "Number of data points: {value}",
  "@numberOfDataPoints": {
    "description": "A message with a formatted int parameter",
    "placeholders": {
      "value": {
        "type": "int",
        "format": "compactCurrency",
        "optionalParameters": {
          "decimalDigits": 2
        }
      }
    }
  }
}

In full ICU MessageFormat syntax, this could be expressed as {value,number,ยค#,##0.##}, or {value,number,currency} for short.

Loco supports ICU MessageFormat, but doesn't hold formatting data outside of the syntax. In order to support Flutter ARB exports, Loco now retains the JSON structure, with the following caveats:

  • It can only be set via file imports and is not editable via the UI
  • The formatting arguments will only be exported to *.arb files
  • It is not currently validated

Inferred placeholder types

Loco already supports "example" and "description" fields for placeholders, but has no way to set a platform-specific type. As of today, ARB exports will infer a Flutter type as follows:

{"type":"num"} will be exported if any of the following apply:

  1. The example value is a numeric string
  2. The message syntax indicates a numeric type (e.g. plurals)
  • No other types are currently inferred, and num is always used in place of int and double.
  • Note that the absence of a type means Object, and not String.

New export parameters

The export API has two new parameters for this format: arb-version and arb-compact.

  • arb-compact will export a stripped down ARB file containing the key/value translation pairs, plus the @@locale field.
    The latter may not be required by Flutter, but is mandatory according to the published schema. This is compatible with Loco's standard no-comments parameter, which omits all @@ header fields, but leaves @key metadata fields. Specifying both will strip the output down to only key/value translation pairs.

  • arb-version has been added in the hope that the ARB schema will at some point be versioned. For the time being, you can retain all of Loco's legacy behaviour by specifying arb-version=legacy. This will observe the schema as per the pre-2018 specification.

Last updated by