I18n¶

Glyph does not own translation files, plural rules, locale fallback, number
formatting, or date formatting. Bring a library such as smiti18n, or any
callable translator, and connect it through ui.i18n.
local smiti18n = require("smiti18n")
ui.i18n.configure({
translate = function(key, params, opts)
local nextParams = {}
for name, value in pairs(params or {}) do
nextParams[name] = value
end
if opts and opts.fallback then
nextParams.default = opts.fallback
end
return smiti18n(key, nextParams)
end,
setLocale = function(locale)
smiti18n.setLocale(locale)
end,
getLocale = function()
return smiti18n.getLocale()
end,
})
Translate¶
Use ui.t or ui.i18n.t when you want the translated string directly:
ui.text(ui.t("menu.title"))
ui.text(ui.t("messages", { count = count }, { cacheKey = "messages:" .. count }))
Missing translations fall back to the key. Pass fallback, or configure
missing, to customize that behavior:
ui.i18n.configure({
translate = translate,
missing = function(key, params, opts)
return opts and opts.fallback or key
end,
})
Keyed Props¶
Most text-bearing primitives accept translation keys:
ui.textKey("hud.ready")
ui.button({ labelKey = "actions.confirm" })
ui.input({ value = query, placeholderKey = "search.placeholder" })
ui.panel({ titleKey = "inventory.title" }, children)
ui.meter({ value = hp, max = maxHp, labelKey = "stats.hp" })
ui.tabs({}, {
{ labelKey = "tabs.map", content = MapPanel() },
{ labelKey = "tabs.log", content = LogPanel() },
})
Each keyed prop also accepts params, fallback, and cache key fields:
ui.textKey("messages", {
textParams = { count = count },
textFallback = "No messages",
textCacheKey = "messages:" .. tostring(count),
})
Accessibility semantics use the same pattern, so labels and spoken values stay localized without hard-coding strings in adapters:
ui.button({
labelKey = "actions.launch",
accessibilityLabelKey = "a11y.actions.launch",
accessibilityDescriptionKey = "a11y.actions.launch_help",
})
Available semantic prefixes are accessibilityLabel,
accessibilityDescription, and accessibilityValueText, each with Params,
Fallback, and CacheKey fields.
Locale Changes¶
Call ui.i18n.setLocale(locale) when the active locale changes. Glyph calls the
configured backend setLocale, clears its translation cache, bumps
ui.i18n.version(), and marks the runtime dirty.
Use the version in memo dependencies for translated static subtrees:
examples/i18n is a responsive game-console style demo with localized command
buttons, status panels, meters, tabs, and a side-by-side comparison of memoized
and unmemoized translated rows. Press the Ping UI button: the large App renders
and Live builds counters keep rising, Memo builds stays stable, and Saved
rebuilds shows the avoided subtree work until the locale or message count
changes.
Cache Rules¶
Glyph caches only translations that are safe to reuse:
- no params: cached by locale, key, fallback, and i18n version
- params with
cacheKey: cached by locale, key, fallback, cache key, and i18n version - params without
cacheKey: translated fresh each time
This keeps mutable param tables from producing stale strings while still making stable labels cheap.