as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support

@amazon-devices/keplerscript-kepleri18n-lib

The Kepler Internationalization (i18n) API enables localization functionality in your apps.

Remarks

As a best practice store UI messages in a resource file that is not part of the source code. The Asset Resolver API enables apps to manage external string resources in Kepler. The API defines both the resource file format and the expected location of string resource files within an application's source directory. Aps can use this API to retrieve localized strings that match the device locale, ensuring users see UI messages in their preferred language.

Get started

Setup

Add the following library dependency to the dependencies section of your package.json file.

Copied to clipboard.

"@amazon-devices/asset-resolver-lib": "~1.0.0", // or latest version
"@amazon-devices/keplerscript-kepleri18n-lib": "~1.0.0", // or latest major version

Usage

The following sections describe how to use the Asset Resolver and Internationalization APIs.

Define Resource Files

The first step is to create resource files in which you will store the string resources. The resource files that you create and own are for text in the source language. The string resource file format is PUFF-J. See PUFF-J page for more details and an extensive PUFF-J sample.

Some rules and best practices to keep in mind:

  1. The file extension for a resource file is .puff.json. A typical PUFF-J resource file name is strings.puff.json.
  2. The character set for resource IDs in PUFF-J is restricted to alphanumeric, underscore, hyphen, and colon. The rule is not currently enforced, but it will be in the near future.
  3. As a best practice, name resource IDs descriptively such that they identify where the resource is used and what the resource is used for. For example, for a string resource used as the Wi-Fi setup dialog title, the ID could be "wifi-setup-dialog-title".
  4. Include enough context for the resource in the note attribute. Especially for strings that have placeholders, provide context on what the placeholders are as well as sample values for the placeholders.
  5. You can organize string resources into multiple PUFF-J files. Keep in mind that resource keys defined in PUFF-J files must be unique across the set of all PUFF-J files in the application. If you do create multiple PUFF-J files, consider prefixing resource keys with application name and file name so that it’s easier to ensure uniqueness of resource keys.

Example PUFF-J file:

Copied to clipboard.

{
    "note": "Resources for App A",
    "dir": "ltr",
    "resources": {
        "wifi-setup-dialog-title": "Connect to Wi-Fi",
        "wifi-setup-network-connected-message": {
            "note": "This message is displayed upon successful connection to a Wi-Fi network. The {ssid} placeholder is the SSID of the connected Wi-Fi network, such as 'Home Network'.",
            "value": "Wi-Fi is successfully connected. Network: {ssid}"
        }
    }
}

The string "Wi-Fi is successfully connected. Network: {ssid}" in the example is a classic message format pattern. For string resources that contain placeholders that are replaced at runtime, do not concatenate strings to form the complete message. Translating string fragments out of context and then concatenating them leads to incorrect translation of the complete message. Kepler provides a message format solution that you can use to write the complete message as a classic message format pattern. Translators can then view and translate the complete message. See Message Format guide on using MessageFormatClassic API and specifying patterns.

PUFF-J also supports number resources. Number resources are represented in double floating-point type.

Resource File Location in Source Repository

Place app source-language PUFF-J files directly in the assets/text/ subdirectory. These are the source files from which your localization provider takes the strings to translate. Localized PUFF-J files are placed in the corresponding assets/text/<BCP-47 language tag>/ subdirectories.

BCP-47 uses a hyphen as the subtag separator, for example en-US, not an underscore which is used in locale IDs on POSIX platforms to separate between language and region fields.

en-US PUFF-J file symbolic links

If the root / source-language PUFF-J files are in American English and en PUFF-J files are in British English, add a en-US subfolder and add symbolic links under en-US subfolder linking to corresponding root PUFF-J files (For example for the example subdirectory tree below: mkdir assets/text/en-US; cd assets/text/en-US; ln -s ../strings.puff.json strings.puff.json). This is to make sure that for the en-US locale, the root PUFF-J files in American English are retrieved before en PUFF-J files in British English."

Example assets/text/ subdirectory tree:

assets
└── text
    ├── strings.puff.json
    ├── en-US
    │   └── strings.puff.json --- symbolic link to root PUFF-J file ---> ../strings.puff.json
    ├── fr
    │   └── strings.puff.json
    ├── fr-CA
    │   └── strings.puff.json
    └── ja
        └── strings.puff.json

Make sure that the assets directory is included in or copied into the source directory from which VPT packaging tool creates the app package. For React Native for Kepler apps, the build tool takes care of that.

API to Retrieve Resources Defined In Resource Files

Use Asset Resolver API to retrieve resources defined in PUFF-J files.

The following example shows how to call AssetResolver.

Copied to clipboard.

import { AssetResolver } from '@amazon-devices/asset-resolver-lib'
...
    const strResource = AssetResolver.getString("desired-resource-id");
    // strResource.value is the resource string.
    // strResource.dir is the text base (written) direction of the resource string as specified in corresponding PUFF-J file.

    const numberResource = AssetResolver.getNumber("another-resource-id");
    // numberResource is the resource number.

Set the dir attribute of a string resource to Text UI widget when the string resource might have a text base direction that is different from the Text UI widget's default text base direction. For example, if an Arabic string resource is displayed in an English UI, set the Text UI widget’s text base direction attribute to this dir attribute value, which is rtl (right to left) as set in the Arabic PUFF-J resource file.

For select and plural string resource types, AssetResolver.getString() returns the resource as a classic message format pattern string. For more information about Resource Types, see Resource Types in the "PUFF-J File Format" topic.

For information about using the MessageFormatClassic class with the returned pattern string to produce the formatted string, see Message Format guide.

String Formatting

Message Format

User-facing messages can have variables such as names, numbers, dates, and time to be filled in at runtime. Localized message translations often have different word ordering based on the target language's grammar. Thus, translators need to be able to move variables around in a message's translation. Translators can only do so when they have the complete message with placeholders for variables. Concatenating phrases based on source language grammar can render the message untranslatable. Kepler provides a message format solution which has placeholders for the variables in the message. Developers can use this message format pattern to write the complete message in a localization friendly manner.

The MessageFormatClassic class adopts the classic ICU MessageFormat pattern. For pattern tutorial and reference, see classic ICU MessageFormat guide. Since the inception of classic ICU MessageFormat patterns, there have been several shifts in the best practices - the most important of them is the use of named arguments, rather than numbered / positional arguments. Please use the named arguments examples as reference. And use the MessageFormatClassic class with the patterns rather than what's shown in code examples there.

NOTE: Unicode has a working group drafting a new message format standard. We will review it for inclusion in Kepler after the standard is released.

MessageFormatClassic supports both named-argument style and numbered-argument style for placeholders in patterns. Named-argument style is recommended because with descriptively named placeholders, both developers and translators benefit from improved readability and can better infer what kind of values goes into a placeholder in a pattern.

Use Message Format in React Native for Kepler

The following procedure shows how to use the MessageFormatClassic class.

  1. Import MessageFormatClassic from the @amazon-devices/keplerscript-kepleri18n-lib package.

    Copied to clipboard.

     import { MessageFormatClassic } from '@amazon-devices/keplerscript-kepleri18n-lib';
    
  2. To use named-argument style pattern in the MessageFormatClassic class, construct a JavaScript built-in Map object populated with argument names and corresponding values. Then pass the populated Map instance as well as the pattern to the MessageFormatClassic.format() method.

    Use the named-argument style pattern instead of the numbered-argument style pattern as shown in the following example.

    Copied to clipboard.

     import { MessageFormatClassic } from '@amazon-devices/keplerscript-kepleri18n-lib';
     ...
         // Retrieve the pattern from the string resources. It's hardcoded here to simplify the example.
         const pattern: string = "Car number {carNumber} wins! Congratulations, {driverName}!";
         const carNumber: number = 3;
         const driverName: string = "Alice";
         const argMap = new Map<string, number | string | Date>();
         argMap.set("carNumber", carNumber);
         argMap.set("driverName", driverName);
         const message: string | null = MessageFormatClassic.format(pattern, argMap);
         if (message === null) {
             // Error
             return;
         }
         // message is "Car number 3 wins! Congratulations, Alice!".
    
  3. To use numbered-argument style pattern in the MessageFormatClassic class, call MessageFormatClassic.formatPositional() method with the pattern and argument values in the numbered-argument order. For example, the value for argument zero {0} is provided first after the pattern parameter. If there is more than one argument in the pattern, it is followed by the value for argument one {1}, and so on.

    The following example shows how to use a numbered-argument style pattern:

    Copied to clipboard.

     import { MessageFormatClassic } from '@amazon-devices/keplerscript-kepleri18n-lib';
     ...
         // Retrieve the pattern from the string resources. It's hardcoded here to simplify the example.
         const pattern: string = "Car number {0} wins! Congratulations, {1}!";
         const carNumber: number = 11;
         const driverName: string = "Bob";
         const message: string | null = MessageFormatClassic.formatPositional(pattern, carNumber, driverName);
         if (message === null) {
             // Error
             return;
         }
         // message is "Car number 11 wins! Congratulations, Bob!".
    

Measurement Units

For formatting measurement units such as for temperature, distance, speed, power, torque, and pressure, use Message Format described above with measurement unit skeletons in pattern:

The following are examples of classic ICU MessageFormat patterns with measurement unit skeletons.

Copied to clipboard.

"Current Temperature: {temperatureInFahrenheit, number, :: unit/fahrenheit}"
// Sample output: "Current Temperature: 70°F".

"{distanceInKilometers, number, :: unit/kilometer unit-width-full-name}"
// Sample outputs: "1 kilometer", "100 kilometers". Notice the plural is already taken care of in the format result.

"{speedInKilometersPerHour, number, :: unit/kilometer-per-hour}"
// Sample output: "50 km/h".

"{speedInMilesPerHour, number, :: unit/mile-per-hour}"
// Sample output: "25 mph".

"{pressureInPSI, number, :: unit/pound-force-per-square-inch}"
// Sample output: "36 psi"

Elapsed Time/Duration

In React Native for Kepler, the ECMAScript Intl.DurationFormat object (Stage 3 Proposal) is available. API documentation and examples are available on Mozilla MDN Web Docs. The TC39 API proposal is on GitHub.

Sorting in Alphabetical And Natural Order / Collation

In React Native for Kepler, the ECMAScript Intl.Collator object is available. API documentation and examples are available on Mozilla MDN Web Docs.

Application / System Locale And Time Zone Preferences

I18nManager provides functions to retrieve, modify, and listen for changes to application locale and time zone preferences. For more information about the API, see the I18nManager section in the React Native for Kepler Internationalization and Localization API.

Modules


Last updated: Sep 30, 2025