Guides and reference: Localization
Guide and reference
Localization
Set the interface language, content language and authored translations separately. Changing the player's language does not translate question content.
This page describes the players' 1.0 prerelease, published under the beta npm tag; see Versioning.
Try it
Build a student's AfA profile, set the administration, the interface locale and the content, and follow
each decision the framework makes: which tools each toolbar shows and which rule decided it, which
catalog the interface loads, which lang lands where, what multiple choice labels itself in,
what read-aloud sends, and which sign-language card resolves. The stages marked Runs execute the
players' own code in this page; the live player loads the same inputs from the CDN.
Loading the framework…
Live section player
Load a section player from the CDN with the same profile, policy and languages as the trace.
Three channels
| Channel | Set by | Governs | AfA PNP 3.0 |
|---|---|---|---|
| Interface locale | The locale attribute | Player status and errors, toolbar labels, tool panels, aria-labels, debug panels, and
the labels of elements that follow it | language-of-interface |
| Content language | lang in the content or the item's env.locale; for read-aloud, also the
toolkit's content-language or the section player's runtime.contentLanguage | lang and dir on the item content, the read-aloud voice | Declared by the content |
| AfA profile | The student's AfA record, through the tool policy; alternates are accessibility catalog cards authored in the item | Which tools each toolbar shows and starts, and which alternate plays: signed video and audio transcripts. Translated keywords and items are not built | spoken, calculator-on-screen, line-reader, sign-language |
Fallback order
Each surface resolves its language on its own, from the first source that has a value.
Interface locale
Set locale on the item player, each section player layout, the toolkit or the assessment
player, which passes it to the section it shows. Unset,
everything renders English. The players bundle two reviewed catalogs: en-US, the source,
and nl-NL. Every catalog other than English loads as a separate chunk, so English pages carry
no other catalog. Changing the attribute re-renders the interface in place, with no reload.
Generated locales
@pie-players/pie-i18n-generated adds 13 machine-generated catalogs: ar, cy, en-AU, en-GB, es, fr, ja, ko, pt, ro, sv, th-TH and zh. None has had a native review yet. CI checks their keys, placeholders, plural forms
and freshness against English, never the quality of the translation.
Installing the package loads nothing. A host opts in by composing its loaders after the bundled ones
and handing the provider to the player: the i18n property on the item player and the
toolkit, or runtime.i18n on a section player layout, which forwards it to the item players
it mounts. Arabic is the first right-to-left locale; its layout has not been audited.
Tag resolution
Tags resolve by RFC 4647 lookup, then by widening to the primary subtag. The generated catalogs
register under bare tags such as es and fr, so regional requests widen onto
them.
| Requested | Catalog | Why |
|---|---|---|
nl-NL | nl-NL | exact match |
nl_NL | nl-NL | POSIX form normalized |
nl-BE | nl-NL | primary subtag widened |
es-MX | es | primary subtag widened, with the generated tier |
en | en-US | en-GB and en-AU stay regional, so bare en keeps US English |
de-DE | de-DE | honored; your messages, then English |
(unset) | en-US | the browser locale is never read |
Your own messages
customMessages adds a locale or overrides shipped keys one at a time, generated catalogs
included, so renaming a label needs no fork. Plurals use Intl.PluralRules with the CLDR
categories.
The players set lang and dir on their own interface subtree and leave the
document's alone. Tools registered by a host name their labels with nameKey and descriptionKey, so they localize with the rest. A coverage check in CI keeps every
bundled catalog complete.
Content language
Content language is the language the item is written in. The interface locale never sets it, so a Dutch interface can read English content in an English voice. Nothing invents one either: content that declares no language stays undeclared.
A host declares it on the item's env as locale. The item player reflects it
onto the item's content root as lang and dir, so a screen reader takes the
content's pronunciation and right-to-left content lays out right to left, whatever the interface
locale.
Read-aloud resolves a language for every read. A lang attribute in the markup wins;
content without one takes the toolkit's content-language, which a section player host sets
through runtime.contentLanguage. A read that finds neither uses the TTS tool's configured
language, then en-US.
| TTS provider | How the language reaches it |
|---|---|
| Browser speech | The configured voice, else a voice for the content language, else the browser's default |
| PIE TTS service (Polly, Google) | Sent as language |
| SchoolCity TTS server | Sent as lang_id |
Browser speech is the one place the browser's language still shows through, and only when nothing
names a language. Elements receive env.locale but none reads it yet, so an element's own
text still follows its interface locale or model.language. Speech-to-text language is
not built.
In-item alternates
An item carries alternates as accessibility catalog cards, each tagged with its language. A spoken lookup, such as read-aloud's, tries the language it asks for, widening es-MX to es, then the toolkit's default language (en-US unless the
host sets accessibility.language), then any card of that type.
The sign-language tool is stricter. It shows the card in the profile's sign language
(ase, American Sign Language, when the profile names none), else a card that names no
sign language, else nothing: PIE never infers a sign language from a spoken one and never shows a card
in another sign language. Signed video and audio transcripts are the alternates that ship; a profile
that asks for keyword or item translation is reported as tool-policy.unknownSupportId and
changes nothing in delivery.
Accessibility catalogs cover authoring and resolution.
Element labels
Elements render their own interface text, such as button labels and feedback. Elements moved onto @pie-element/shared-i18n follow the players' interface locale: the item player and the
toolkit publish it to the elements inside them, and such an element renders in it, else in the item's
authored model.language, else en-US. Multiple choice is the first, together
with the libraries it renders through. It ships English, a reviewed Spanish, and machine-generated nl-NL and the same 13 locales as the players; its IIFE build ships
English only. A host renames or adds element strings with registerMessages.
The other pie-elements-ng elements still render in model.language and ship English and
Spanish (en_US and es_ES), independent of the players' locale.
Neither path reads the browser locale.
Internationalization design(opens in new tab) · Interface i18n(opens in new tab) · Generated locales(opens in new tab) · Section player README(opens in new tab) · Element i18n(opens in new tab) · Element i18n PRD(opens in new tab)