i18n
Clover translates its own words: the names of its controls, its messages, and what it announces. IIIF text (a label, a summary, metadata) is the resource’s own, in the languages it has, and Clover chooses among them as Composing layouts describes.
Clover has its own translator, well under 1 kB gzipped, with no translation library to
install. Its strings are kept the way i18next keeps them, so initCloverI18n calls from
Clover 3.x keep working.
Languages Clover ships
Each is complete: it has every string English has, which a test checks.
Pick one to hear the Viewer in it. This page is in English, so each of Clover’s words in
another language carries that language’s lang.
How Clover chooses
Clover speaks the language of the page around it. To find it, Clover looks in this order:
- First, it checks for a language you set yourself, with
initCloverI18n({ lng }). - Then, it reads the page it is on, for the language in its
<html lang>. - Then, it looks at the reader’s browser, and takes the first of their languages that Clover ships.
- Last, for any string the language it chose does not have, it uses the
fallbackLngyou give, and then English.
A regional tag tries its base language too, so pt-BR falls back to pt.
Setting a language
Call initCloverI18n near your app’s entry point, before Clover draws:
import { initCloverI18n } from "@nulib/clover";
initCloverI18n({ lng: "fr" });<script type="module">
import { initCloverI18n } from "@nulib/clover/web-components";
initCloverI18n({ lng: "fr" });
</script>It can be called again: each call merges its resources and applies any lng or
fallbackLng it is given, and every Clover part on the page changes language at once.
The web components take the same call; see
Languages in the technical overview.
A language Clover does not ship
Give its strings as resources, under the clover namespace:
import { initCloverI18n } from "@nulib/clover";
initCloverI18n({
lng: "de",
resources: {
de: {
clover: {
commonClose: "Schließen",
informationPanelTabs: "Informationsbereich",
},
},
},
});<script type="module">
import { initCloverI18n } from "@nulib/clover/web-components";
initCloverI18n({
lng: "de",
resources: {
de: {
clover: {
commonClose: "Schließen",
informationPanelTabs: "Informationsbereich",
},
},
},
});
</script>Any string you leave out falls back to English, marked lang="en". The full list of
keys, with their English, is
en.json.
A string with {{name}} in it is filled in by Clover: keep each placeholder as it is.
Loading
English comes with Clover. Each other language is its own file, loaded the first time
Clover is to speak it, so a page in English never fetches one. Until it arrives, Clover’s
words are shown in English, marked lang="en", and they change when it does. A page
rendered on the server, or a test, that needs them in place first waits for them:
await initCloverI18n({ lng: "fr" }).ready();Marking languages
Where one of Clover’s strings is not in the page’s language (a French reader on an
English page, or a string that fell back to English), the element that shows it, or is
named by it, carries its language as lang, so a screen reader pronounces it correctly
(WCAG 3.1.2). The page’s language is the nearest lang around the Root<clover-root>, or one you give
the Root<clover-root>. A part of your own does the same with useT and useLangOf, as
Languages in Composing layouts shows.
Adding a language to Clover
A language added to Clover itself ships to everyone. In nulib-ds/clover :
- Add
packages/clover/src/i18n/locales/<tag>.json, with every keyen.jsonhas, translated. Keep each{{name}}placeholder as it is. - Add its loader to
loadersinpackages/clover/src/i18n/locales/index.ts, so it loads only when it is needed. - Run
npm test.locales.test.tschecks that the file has every key English has and no other, and that each placeholder is kept. A word your language spells as English does (French “Collection”) goes on that test’sSAME_AS_ENGLISHlist for your language. - Add a line under
## Unreleasedinpackages/clover/CHANGELOG.md, and open a pull request.
{
"commonClose": "Schließen",
"commonNext": "Weiter",
"commonPrevious": "Zurück"
}export const loaders: Record<string, LocaleLoader> = {
de: () => import("./de.json"),
es: () => import("./es.json"),
// …
};For a regional variant, name the file by its full tag (fr-CA.json) and give its loader
the same key ("fr-CA"); readers of that region get it, and others the base language.
A new key in en.json is added to every locale, translated, in the same change, and the
test fails until it is. If you speak one of the languages Clover ships, a review of its
strings is welcome, as an issue or a pull request.