npm
Source
Description
Plugin for@wolfstar/http-framework that adds an internationalization layer powered by i18next and @wolfstar/i18next-backend.
It merges two upstream implementations:
@wolfstar/http-framework-i18n— the HTTP-interaction helpers (getSupportedLanguageT,applyLocalizedBuilder, localized builders).@sapphire/plugin-i18next— the plugin architecture (container.i18n,InternationalizationHandler, customfetchLanguage, formatters, HMR).
discord-api-types structures instead of discord.js class instances.
Installation
Usage
Import the register entrypoint before creating the client:Languages directory
.json file is a namespace (commands/ping).
Typed keys
Keys are typed through i18next’s ownCustomTypeOptions augmentation. Generate it from the locale
files with
@wolfstar/i18next-type-generator,
listed as an optional peer dependency — nothing at runtime depends on it, only the generated types
consumers opt into:
CustomTypeOptions.resources. If defaultNS is set to anything other than
i18next’s own 'translation' default — this plugin’s defaultLanguageDirectory layout usually
implies 'default' — declare it separately, or every helper’s default namespace stops satisfying
i18next’s Namespace type:
Consumption
getSupported*T helpers are synchronous and only read the locales carried by the interaction. Use
the asynchronous fetch* helpers when the language comes from somewhere else — they go through
container.i18n.fetchLanguage:
Targets
Every helper accepts any of four raw payloads, told apart structurally — the framework never hasdiscord.js class instances to check with instanceof:
APIInteraction, APIMessage, APIChannel and APIGuild all satisfy the matching target, so
payloads can be passed straight through:
defaultName for them. Use the asynchronous fetch* helpers instead: the hook receives the
target’s guildId, channelId and userId, which is enough to look the language up.
Localizing command builders
<root>Name and <root>Description; passing two keys uses them
verbatim.
[!IMPORTANT] Builder localization reads the loaded resources, so it may only run after thepreLoadhook has initialized the handler. The plugin already guarantees this ordering for pieces loaded byClient#load.
Hot module replacement
container.i18n.reloadResources() runs on every
addition, change or deletion — including new locale directories and new namespace files, which are
registered on i18next and become usable without a restart.
ignoreInitial defaults to true so the files already on disk do not each trigger a reload on
startup; pass hmr.options to override it or any other chokidar option. The watcher is exposed as
I18nextPlugin.watcher, so it can be closed on shutdown:
Options
Migrating from @wolfstar/http-framework-i18n
@wolfstar/http-framework-i18n is deprecated in favour
of this plugin. The upstream changes are documented in
wolfstar-project/stars-components#30; the short version:
getSupportedLanguageName, getSupportedUserLanguageName, getSupportedLanguageT,
getSupportedUserLanguageT (which now also take the key and its options directly, like resolveKey
did), supportedLanguages, isSupportedDiscordLocale, getLocalizedData,
applyNameLocalizedBuilder, applyDescriptionLocalizedBuilder, applyLocalizedBuilder and
createSelectMenuChoiceName keep the same names and signatures — only the module specifier changes.
T, FT, resolveKey and resolveUserKey were removed upstream in
wolfstar-project/stars-components#30 and are gone here
too — see Migrating off T / FT / resolve* below.
Other differences: @wolfstar/http-framework@^3.1.0 is now a peer dependency, i18next moves from ^22 to ^25, and
the locales directory defaults to <root>/languages instead of an explicit path passed to load() — the layout itself
is unchanged.
Migrating off T / FT / resolve*
The branded-key helpers were replaced by i18next’s native TypeScript support, so keys are plain
strings typed by the CustomTypeOptions augmentation
@wolfstar/i18next-type-generator emits.
TFunction#lng (along with lngs, ns and keyPrefix) is still declared, so code reading the
language off a bound function keeps working — i18next assigns them on every function getFixedT
returns but does not type them.
LocalePrefixKey is no longer hardcoded to commands/<file>:<key>: it is now
`${string}${LocaleSeparator}${string}`, with LocaleSeparator read from i18next’s
TypeOptions["nsSeparator"].
Credits
Adapted from@wolfstar/http-framework-i18n and @sapphire/plugin-i18next (MIT).