howdy/i18n
Translations for Howdy apps.
A Translator is a locale with everything needed to write in it:
the locales to fall back to, plural rules, and the CLDR data that
howdy/i18n/format writes numbers, dates and lists with.
let t = i18n.new("de-CH")
messages.cart_items(t, count: 3) // "3 Artikel"
format.date(t, today, format.Long) // "19. Oktober 2026"
Messages live in JSON catalogues, one per locale, written in ICU
MessageFormat, and gleam run -m howdy/i18n/cli gen turns them into a
Gleam module with a function for each message. See howdy/i18n/cli.
Pass the tag howdy/locale chose for the request: i18n.new( locale.to_string(locale.detect(ctx, locales))). This package does not
depend on Howdy itself, so it also works in code compiled to
JavaScript.
Types
pub opaque type Translator
Values
pub fn canonical(tag: String) -> String
A tag in canonical case, with _ read as -: zh-Hant-TW. Chinese for
Taiwan, Hong Kong and Macau gains its traditional script.
pub fn cldr_version() -> String
The version of CLDR the data and plural rules come from.
pub fn data_locale(translator: Translator) -> String
The locale whose formatting data the translator uses.
pub fn data_locales() -> List(String)
The locales with formatting data of their own.
pub fn fallbacks(translator: Translator) -> List(String)
The locale and those it falls back to, most specific first:
es-AR, es-419, es.
pub fn language_name(locale: String) -> Result(String, Nil)
The name of a locale in its own language, such as Deutsch for de,
for a language switcher. Error for a locale without data.
pub fn new(locale: String) -> Translator
A translator for a BCP 47 tag such as pt-BR. Any tag works: one
without data of its own uses the nearest locale that has some, and
English in the end.
pub fn pick(
translator: Translator,
available: List(String),
) -> String
Which of available catalogue locales to use: the first the
translator falls back to, or one of the same language, or "" when
there is none. Generated catalogues call this to choose their words.