Skip to main content

npm

Source

Coming from @wolfstar/http-framework-i18n? Follow the migration guide.
WolfStar

@wolfstar/plugin-i18next

i18next-powered internationalization for HTTP interactions.version downloads license

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, custom fetchLanguage, formatters, HMR).
Interactions arrive over HTTP as raw payloads, so every helper operates on discord-api-types structures instead of discord.js class instances.

Installation

Usage

Import the register entrypoint before creating the client:
The plugin registers three hooks:

Languages directory

Every top-level directory is a language, every nested .json file is a namespace (commands/ping).

Typed keys

Keys are typed through i18next’s own CustomTypeOptions 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:
The generator only emits 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:
See i18next’s TypeScript guide for the other options the augmentation accepts. Without any of this every helper still accepts plain strings, only untyped.

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 has discord.js class instances to check with instanceof: APIInteraction, APIMessage, APIChannel and APIGuild all satisfy the matching target, so payloads can be passed straight through:
Channels and messages carry no locale of their own, so the synchronous helpers fall back to 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

Passing a single root key resolves <root>Name and <root>Description; passing two keys uses them verbatim.
[!IMPORTANT] Builder localization reads the loaded resources, so it may only run after the preLoad hook has initialized the handler. The plugin already guarantees this ordering for pieces loaded by Client#load.

Hot module replacement

When enabled, the languages directory is watched and 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).