### Configure Plugin Options Example Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/types.md A complete example showing how to instantiate and configure the plugin options. ```typescript const options: I18NextPluginOptions = { instance: createInstance(), initOptions: { lng: "en", fallbackLng: "en", resources: { en: { translation: { hello: "Hello", world: "World", }, }, }, }, detectLanguage: newLanguageDetector({ searchParamName: "lang", storeParamName: "language", headerName: "accept-language", cookieName: "lang", pathParamName: "lang", }), }; ``` -------------------------------- ### Install elysia-i18next Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/README.md Install the package and its dependency using the Bun package manager. ```bash bun add elysia-i18next i18next ``` -------------------------------- ### Verify Installed Versions Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Use npm to check that the installed versions of elysia and i18next meet the requirements. ```bash # Verify installed versions npm ls elysia i18next # Should show: # elysia@1.1.22 (or higher) # i18next@23.5.1 (or higher) ``` -------------------------------- ### Basic Plugin Usage Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/i18next-plugin.md Example of initializing the plugin with translation resources and using the 't' function in routes. ```typescript import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; new Elysia() .use( i18next({ initOptions: { lng: "en", resources: { en: { translation: { greeting: "Hello", farewell: "Goodbye", }, }, fr: { translation: { greeting: "Bonjour", farewell: "Au revoir", }, }, }, }, }), ) .get("/", ({ t }) => ({ message: t("greeting") })) .get("/bye", ({ t }) => ({ message: t("farewell") })) .listen(3000); ``` -------------------------------- ### Configure elysia-i18next Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/complete-reference.md Examples for initializing the plugin with various configurations. ```typescript new Elysia() .use(i18next({ initOptions: { lng: "en" } })) .get("/", ({ t }) => t("key")) .listen(3000); ``` ```typescript new Elysia() .use( i18next({ initOptions: { lng: "en", fallbackLng: "en", resources: { en: { translation: { hello: "Hello" } }, de: { translation: { hello: "Hallo" } }, }, }, }), ) .listen(3000); ``` ```typescript const detector: LanguageDetector = (ctx) => { return ctx.request.headers.get("accept-language")?.split(",")[0] || null; }; new Elysia() .use(i18next({ detectLanguage: detector, initOptions: { /* ... */ } })) .listen(3000); ``` ```typescript const i18nInstance = createInstance({ /* config */ }); new Elysia() .use(i18next({ instance: i18nInstance })) .listen(3000); ``` -------------------------------- ### Initialize LanguageDetector Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/types.md Example of configuring and initializing the language detector with required options. ```typescript import { LanguageDetectorOptions, newLanguageDetector } from "elysia-i18next"; const opts: LanguageDetectorOptions = { storeParamName: "userLang", searchParamName: "locale", headerName: "x-locale", cookieName: "userLocale", pathParamName: "locale", }; const detector = newLanguageDetector(opts); ``` -------------------------------- ### Initialize elysia-i18next plugin Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/README.md Basic setup for integrating i18next into an Elysia application with translation resources. ```typescript import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; new Elysia() .use( i18next({ initOptions: { lng: "en", resources: { en: { translation: { hello: "Hello" } }, de: { translation: { hello: "Hallo" } }, }, }, }), ) .get("/", ({ t }) => t("hello")) .listen(3000); ``` -------------------------------- ### Advanced i18n Configuration and Usage Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/request-context.md Examples for using fixed namespaces and changing languages within a request handler. ```typescript const resources = { en: { navigation: { home: "Home", about: "About" }, errors: { notFound: "Not Found" }, }, }; .get("/", ({ i18n }) => { // Get translation function bound to "navigation" namespace const tNav = i18n.getFixedT(null, "navigation"); return { home: tNav("home"), about: tNav("about") }; }) ``` ```typescript .get("/german", async ({ i18n, t }) => { await i18n.changeLanguage("de"); return { greeting: t("greeting") }; }) ``` -------------------------------- ### Unit Test Setup for Elysia i18next Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Uses bun:test to verify translation functionality within an Elysia application instance. ```typescript import { describe, it, expect, beforeEach } from "bun:test"; import { createInstance } from "i18next"; import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; describe("i18next plugin", () => { let instance: i18n; beforeEach(() => { instance = createInstance({ lng: "en", resources: { en: { translation: { test: "Test" } }, }, }); }); it("should translate", async () => { const app = new Elysia() .use(i18next({ instance })) .get("/", ({ t }) => t("test")); const res = await app.handle(new Request("http://localhost/")); expect(await res.text()).toBe("Test"); }); }); ``` -------------------------------- ### Access Translation and Context in Routes Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/request-context.md Examples of accessing the translation function and i18n instance within route handlers. ```typescript .get("/", ({ t }) => { return { greeting: t("greeting") }; }) ``` ```typescript .get("/info", ({ t, i18n }) => { return { language: i18n.language, greeting: t("greeting"), direction: i18n.dir(), }; }) ``` ```typescript import { Context } from "elysia"; import { I18NextRequest } from "elysia-i18next"; .get("/typed", (context: Context & I18NextRequest) => { const { t, i18n } = context; return { greeting: t("greeting") }; }) ``` -------------------------------- ### Implement Custom Language Detector Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/module-structure.md Example of using exported types to define a custom language detector with full TypeScript support. ```typescript import { i18next, LanguageDetector, I18NextPluginOptions } from "elysia-i18next"; const customDetector: LanguageDetector = (ctx) => { // TypeScript provides autocomplete on ctx return ctx.request.headers.get("accept-language"); }; const options: I18NextPluginOptions = { detectLanguage: customDetector, // ... }; ``` -------------------------------- ### Language Negotiation via URL Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/examples.md Demonstrates how to handle language selection dynamically based on URL parameters. ```typescript .use( i18next({ initOptions: { lng: "en", supportedLngs: ["en", "de", "fr"], resources: { en: { translation: { greeting: "Hello" } }, de: { translation: { greeting: "Hallo" } }, fr: { translation: { greeting: "Bonjour" } }, }, }, }), ) .get("/:lang/greet", ({ t, params }) => ({ message: t("greeting"), language: params.lang, })) ``` -------------------------------- ### Display project file structure Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/INDEX.md Visual representation of the project directory layout. ```text /workspace/home/output/ ├── INDEX.md (this file) ├── README.md (start here) ├── getting-started.md (quick start) ├── configuration.md (all options) ├── complete-reference.md (all APIs, 1 file) ├── types.md (type definitions) ├── examples.md (code examples) ├── advanced-usage.md (advanced patterns) ├── module-structure.md (internals) ├── migration-guide.md (compatibility) └── api-reference/ ├── README.md (API overview) ├── i18next-plugin.md (i18next function) ├── language-detector.md (detector function) └── request-context.md (context properties) ``` -------------------------------- ### Configure i18next Initialization Options Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Avoid common pitfalls like infinite loops or production debug settings when configuring i18next. ```typescript // Avoid infinite loops in custom i18next config const options = { lng: "en", // Don't set initImmediate: true if using async detector // Don't set debug: true in production resources: { /* ... */ } }; ``` -------------------------------- ### Production Environment Configuration Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Configures i18next initialization options using environment variables for language settings and server port. ```typescript const i18nConfig = { lng: process.env.DEFAULT_LANGUAGE || "en", fallbackLng: process.env.FALLBACK_LANGUAGE || "en", debug: process.env.NODE_ENV === "development", resources: loadTranslations(), // Load from external source }; new Elysia() .use(i18next({ initOptions: i18nConfig })) .listen(parseInt(process.env.PORT || "3000")); ``` -------------------------------- ### Initialize i18next with Backend Plugins Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/advanced-usage.md Pre-initialize an i18next instance with plugins like i18next-http-backend before passing it to the Elysia plugin. ```typescript import { createInstance } from "i18next"; import HttpBackend from "i18next-http-backend"; const i18nInstance = createInstance(); // Add http backend plugin i18nInstance.use(HttpBackend); // Configure options await i18nInstance.init({ backend: { loadPath: "/locales/{{lng}}/{{ns}}.json", }, ns: ["common", "api"], defaultNS: "common", }); new Elysia() .use(i18next({ instance: i18nInstance })) .listen(3000); ``` -------------------------------- ### Define Default Plugin Options Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/module-structure.md Shows the default configuration structure, including the language detector initialization. ```typescript const defaultOptions: I18NextPluginOptions = { instance: null, initOptions: {}, detectLanguage: newLanguageDetector({ searchParamName: 'lang', storeParamName: 'language', headerName: 'accept-language', cookieName: 'lang', pathParamName: 'lang', }), } ``` -------------------------------- ### Merge Configuration Options Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/module-structure.md Demonstrates how user-provided options override the default plugin configuration. ```typescript const options: I18NextPluginOptions = { ...defaultOptions, // Default options first ...userOptions, // User options override } ``` -------------------------------- ### Plugin Execution Flow Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/INDEX.md Visual representation of the plugin lifecycle from initialization to request handling. ```text app.use(i18next({options})) ↓ Per Request: 1. Derive hook → Clone i18next instance 2. Before-handle hook → Detect language 3. Route handler → Use t() to translate ``` -------------------------------- ### Configure Custom Language Detector Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/language-detector.md Demonstrates creating a custom detector with specific parameter names and integrating it into an Elysia application. ```typescript import { Elysia } from "elysia"; import { i18next, newLanguageDetector } from "elysia-i18next"; // Create a custom detector with alternative parameter names const customDetector = newLanguageDetector({ searchParamName: "locale", storeParamName: "userLanguage", headerName: "x-language", cookieName: "userLocale", pathParamName: "locale", }); new Elysia() .use( i18next({ detectLanguage: customDetector, initOptions: { lng: "en", resources: { en: { translation: { hello: "Hello" } }, de: { translation: { hello: "Hallo" } }, }, }, }), ) .get("/:locale/", ({ t }) => ({ greeting: t("hello") })) .listen(3000); // Request to /de/ will set language to "de" ``` -------------------------------- ### Configure i18next with environment variables Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/configuration.md Uses process.env to dynamically set the default language and fallback behavior during plugin initialization. ```typescript import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; const defaultLanguage = process.env.DEFAULT_LANG || "en"; const enableFallback = process.env.ENABLE_FALLBACK !== "false"; new Elysia() .use( i18next({ initOptions: { lng: defaultLanguage, fallbackLng: enableFallback ? "en" : false, // ... other options }, }), ) .listen(3000); ``` -------------------------------- ### Configure Multiple Translation Namespaces Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/getting-started.md Organizes translations into logical groups and demonstrates how to access them using namespace prefixes. ```typescript new Elysia() .use( i18next({ initOptions: { lng: "en", ns: ["common", "api"], defaultNS: "common", resources: { en: { common: { greeting: "Hello", farewell: "Goodbye", }, api: { success: "Request successful", error: "Request failed", }, }, }, }, }), ) .get("/", ({ t }) => ({ greeting: t("greeting"), // Uses "common" namespace message: t("api:success"), // Explicitly use "api" namespace })) .listen(3000); ``` -------------------------------- ### Configure Multiple Namespaces Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/configuration.md Shows how to organize translations into multiple namespaces and access them explicitly using the t() function. ```typescript new Elysia() .use( i18next({ initOptions: { lng: "en", ns: ["common", "menu", "errors"], defaultNS: "common", resources: { en: { common: { greeting: "Hello", }, menu: { home: "Home", about: "About", }, errors: { notFound: "Page not found", }, }, }, }, }), ) .get("/", ({ t }) => ({ greeting: t("greeting"), // Uses default "common" namespace home: t("menu:home"), // Explicitly use "menu" namespace error: t("errors:notFound"), // Explicitly use "errors" namespace })) .listen(3000); ``` -------------------------------- ### Configure custom language detector Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/complete-reference.md Shows how to instantiate a language detector with custom parameter names and apply it to the i18next plugin. ```typescript const detector = newLanguageDetector({ searchParamName: "lang", storeParamName: "language", headerName: "accept-language", cookieName: "lang", pathParamName: "lang", }); new Elysia().use(i18next({ detectLanguage: detector })).listen(3000); ``` -------------------------------- ### Handle i18next initialization errors Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/complete-reference.md Use a try-catch block to capture and log errors during the i18next instance initialization process. ```typescript try { const instance = createInstance(); await instance.init(options); } catch (error) { console.error("i18next init failed:", error); } ``` -------------------------------- ### Import elysia-i18next in CommonJS Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Syntax for importing the plugin in CommonJS environments using require. ```javascript const { i18next } = require("elysia-i18next"); ``` -------------------------------- ### Define Peer Dependencies Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Specify required versions for elysia and i18next in your package.json. ```json { "peerDependencies": { "elysia": ">= 1.0.1", "i18next": ">= 23.5.1" } } ``` -------------------------------- ### Module Dependency Graph Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/module-structure.md Visual representation of the module hierarchy and external peer dependencies. ```text src/index.ts ├── Exports (public) │ ├── i18next() │ ├── newLanguageDetector() │ ├── I18NextPluginOptions │ ├── I18NextRequest │ ├── LanguageDetector │ └── LanguageDetectorOptions │ └── Dependencies ├── elysia (peer) │ ├── Context │ ├── RouteSchema │ └── Elysia (class) │ └── i18next (peer) ├── InitOptions └── i18n (interface) ``` -------------------------------- ### Serve Content in Multiple Languages Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/README.md Configure the plugin with supported languages and use the translation function within route handlers. ```typescript new Elysia() .use( i18next({ initOptions: { lng: "en", supportedLngs: ["en", "de", "fr"], resources: { /* ... */ }, }, }), ) .get("/:lang/page", ({ t }) => ({ content: t("pageContent") })) .listen(3000); // GET /en/page → English // GET /de/page → German // GET /fr/page → French ``` -------------------------------- ### Use a Custom i18next Instance Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/configuration.md Demonstrates how to pass a pre-configured i18next instance to the Elysia plugin instead of relying on internal initialization. ```typescript import { Elysia } from "elysia"; import { createInstance } from "i18next"; import { i18next } from "elysia-i18next"; const i18nInstance = createInstance({ lng: "fr", fallbackLng: "en", resources: { en: { translation: { greeting: "Hello" }, }, fr: { translation: { greeting: "Bonjour" }, }, }, }); new Elysia() .use(i18next({ instance: i18nInstance })) .get("/", ({ t }) => ({ message: t("greeting") })) .listen(3000); ``` -------------------------------- ### i18next(options) Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/README.md Initializes the i18next plugin for an Elysia instance. It provides a 't' function in the request context for translations. ```APIDOC ## i18next(options) ### Description Initializes the i18next plugin for Elysia.js. Once configured, it injects the 't' translation function into the request context. ### Parameters - **initOptions** (i18next.InitOptions) - Optional - Configuration options for i18next. - **detectLanguage** (LanguageDetector) - Optional - Custom function for detecting the language from the request context. - **instance** (i18next.i18n) - Optional - An existing i18next instance to use instead of the global one. ### Usage Example ```ts import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; new Elysia() .use( i18next({ initOptions: { lng: "nl", resources: { en: { translation: { greeting: "Hi" } }, nl: { translation: { greeting: "Hallo" } } } } }) ) .get("/", ({ t }) => t("greeting")) .listen(3000); ``` ``` -------------------------------- ### Default Detector Configuration Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/language-detector.md Shows the default configuration settings used by the i18next plugin. ```typescript newLanguageDetector({ searchParamName: "lang", storeParamName: "language", headerName: "accept-language", cookieName: "lang", pathParamName: "lang", }) ``` -------------------------------- ### Importing plugin components Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/module-structure.md Directly import the main plugin function, language detector factory, and relevant types from the package. ```typescript import { i18next, newLanguageDetector } from "elysia-i18next"; import type { LanguageDetector, I18NextPluginOptions } from "elysia-i18next"; ``` -------------------------------- ### Integrate i18next Interfaces Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Use the standard i18next interfaces for instance creation and initialization options. ```typescript import lib, { i18n, InitOptions } from 'i18next' // These are the interfaces used const instance: i18n = createInstance() const options: InitOptions = { lng: "en" } ``` -------------------------------- ### Import Type Definitions Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/README.md Import necessary TypeScript types for plugin configuration and language detection. ```typescript import type { I18NextPluginOptions, LanguageDetector, } from "elysia-i18next"; ``` -------------------------------- ### Import elysia-i18next in ESM and Bun Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Standard import syntax for ESM-based environments and native Bun support. ```typescript import { i18next } from "elysia-i18next"; ``` -------------------------------- ### Implement Detector with Store Access Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/types.md A detector that utilizes the Elysia store and request headers to determine the language. ```typescript const storeDetector: LanguageDetector = (ctx) => { // Check authenticated user's language preference in store if (ctx.store.user?.language) { return ctx.store.user.language; } // Fall back to Accept-Language header return ctx.request.headers.get("accept-language")?.split(",")[0] || null; }; ``` -------------------------------- ### Default Plugin Configuration Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/complete-reference.md Default values used when initializing the plugin. ```typescript { instance: null, initOptions: {}, detectLanguage: newLanguageDetector({ searchParamName: 'lang', storeParamName: 'language', headerName: 'accept-language', cookieName: 'lang', pathParamName: 'lang', }) } ``` -------------------------------- ### Request Isolation Demonstration Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/request-context.md Shows how concurrent requests maintain independent i18n instances. ```typescript import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; new Elysia() .use( i18next({ initOptions: { lng: "en", resources: { en: { translation: { greeting: "Hello" } }, de: { translation: { greeting: "Hallo" } }, }, }, }), ) .get("/", ({ i18n }) => { return { language: i18n.language }; }) .listen(3000); // Request 1: GET /?lang=en // Returns: { language: "en" } // i18n instance #1 is cloned and set to English // Request 2: GET /?lang=de (concurrent with Request 1) // Returns: { language: "de" } // i18n instance #2 is cloned and set to German // Request 1's instance #1 is unaffected // Request 3: GET / (falls back to default) // Returns: { language: "en" } // i18n instance #3 is cloned and set to default language ``` -------------------------------- ### Initialize i18next Instance Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/module-structure.md Checks if the i18next instance is initialized and performs initialization if necessary upon the first request. ```typescript const _instance = options.instance || lib // lib is i18next if (!_instance.isInitialized) { await _instance.init(options.initOptions) } ``` -------------------------------- ### Organize Translations with Namespaces Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/README.md Use multiple namespaces to categorize translation resources and access them via scoped keys. ```typescript new Elysia() .use( i18next({ initOptions: { lng: "en", ns: ["common", "api", "errors"], defaultNS: "common", resources: { en: { common: { title: "Home" }, api: { success: "OK" }, errors: { notFound: "Not Found" }, }, }, }, }), ) .get("/", ({ t }) => ({ title: t("title") })) .get("/status", ({ t }) => ({ status: t("api:success") })) .listen(3000); ``` -------------------------------- ### Initialize Elysia i18next Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/README.md Register the i18next plugin in an Elysia application with translation resources. ```typescript import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; new Elysia() .use( i18next({ initOptions: { lng: "nl", resources: { en: { translation: { greeting: "Hi", }, }, nl: { translation: { greeting: "Hallo", }, }, }, }, }), ) .get("/", ({ t }) => t("greeting")) // returns "Hallo" .listen(3000); ``` -------------------------------- ### Import Plugin Correctly Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Ensure the plugin is imported from the main package export. ```typescript // ✓ Correct import { i18next } from "elysia-i18next"; // Check old code for variations ``` -------------------------------- ### Using an Existing i18next Instance Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/getting-started.md Integrates an externally created and initialized i18next instance into the Elysia application. ```typescript import { createInstance } from "i18next"; import { i18next } from "elysia-i18next"; const i18nInstance = createInstance({ lng: "en", resources: { /* ... */ }, }); // Initialize before use (optional, plugin does this automatically) await i18nInstance.init(); const app = new Elysia() .use( i18next({ instance: i18nInstance, }), ) .get("/", ({ t }) => t("greeting")) .listen(3000); ``` -------------------------------- ### Register Global Before-Handle Hook Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/module-structure.md Detects the language from the request context and updates the i18n instance accordingly. ```typescript .onBeforeHandle({ as: "global" }, async ctx => { const lng = await options.detectLanguage(ctx) if (lng) { await ctx.i18n.changeLanguage(lng) } }) ``` -------------------------------- ### Implement RTL language support Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/examples.md Detect text direction using i18n.dir() to adjust UI layout properties dynamically. ```typescript .get("/page", ({ i18n, t }) => { const isRTL = i18n.dir() === "rtl"; return { content: t("pageContent"), direction: isRTL ? "rtl" : "ltr", className: isRTL ? "text-right" : "text-left", }; }) // For Arabic, Hebrew, Farsi, etc. // i18n.dir() returns "rtl" // For English, German, etc. // i18n.dir() returns "ltr" ``` -------------------------------- ### Configure TypeScript for elysia-i18next Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Recommended compiler options for projects using elysia-i18next to ensure compatibility with modern module resolution. ```json { "compilerOptions": { "target": "ES2020", "module": "ESNext", "lib": ["ES2020"], "moduleResolution": "bundler", "strict": true, "jsx": "react-jsx" } } ``` -------------------------------- ### Implement Asynchronous Detector Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/types.md An asynchronous implementation that fetches user preferences from a database. ```typescript const asyncDetector: LanguageDetector = async (ctx) => { // Look up user's preferred language from database const userId = ctx.params.userId; const user = await db.users.findById(userId); return user?.preferredLanguage || null; }; ``` -------------------------------- ### Implement Simple Synchronous Detector Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/types.md A basic implementation that returns a static language code. ```typescript import { LanguageDetector } from "elysia-i18next"; const detector: LanguageDetector = (ctx) => { // Always return English return "en"; }; ``` -------------------------------- ### Initialize Language Detector Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/language-detector.md Defines the signature for the newLanguageDetector factory function. ```typescript export function newLanguageDetector(opts: LanguageDetectorOptions): LanguageDetector ``` -------------------------------- ### Organize translations with namespaces in Elysia Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/examples.md Use multiple namespaces to categorize translation keys. Specify the default namespace and access keys using the 'namespace:key' syntax. ```typescript .use( i18next({ initOptions: { lng: "en", ns: ["common", "auth", "errors", "api"], defaultNS: "common", resources: { en: { common: { appName: "MyApp", home: "Home", }, auth: { login: "Login", register: "Register", }, errors: { notFound: "Not found", unauthorized: "Unauthorized", }, api: { success: "Request successful", }, }, }, }, }), ) .get("/", ({ t }) => ({ title: t("appName") })) .post("/login", ({ t }) => ({ label: t("auth:login") })) .get("/404", ({ t }) => ({ error: t("errors:notFound") })) .post("/api/data", ({ t }) => ({ message: t("api:success") })) ``` -------------------------------- ### i18next(userOptions) Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/i18next-plugin.md The main plugin function that integrates i18next into an Elysia application. It returns a plugin that can be applied using the .use() method, enabling language detection and translation context injection. ```APIDOC ## i18next(userOptions) ### Description A higher-order function that returns a plugin for Elysia. It initializes i18next, manages request-scoped instances, and injects `i18n` and `t` into the request context. ### Signature `export const i18next = (userOptions: Partial) => (app: Elysia) => Elysia` ### Parameters - **userOptions** (Partial) - Required - Configuration options for the i18next plugin, merged with default settings. ### Usage Example ```typescript import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; new Elysia() .use( i18next({ initOptions: { lng: "en", resources: { en: { translation: { greeting: "Hello" } }, fr: { translation: { greeting: "Bonjour" } }, }, }, }), ) .get("/", ({ t }) => ({ message: t("greeting") })) .listen(3000); ``` ``` -------------------------------- ### newLanguageDetector(opts) Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/README.md Creates a custom language detector instance for use with the i18next plugin. ```APIDOC ## newLanguageDetector(opts) ### Description Creates a language detector that allows for custom parameter names when identifying the user's preferred language from headers, cookies, or query parameters. ### Parameters - **opts** (LanguageDetectorOptions) - Required - Configuration object defining parameter names for detection (e.g., searchParamName, headerName, cookieName). ``` -------------------------------- ### Importing elysia-i18next API Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/README.md Import the main plugin functions and type definitions from the package. ```typescript import { i18next, newLanguageDetector } from "elysia-i18next"; import type { I18NextPluginOptions, I18NextRequest, LanguageDetector, LanguageDetectorOptions, } from "elysia-i18next"; ``` -------------------------------- ### i18next(options) Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/README.md The main plugin function used to configure and register i18next within an Elysia application. ```APIDOC ## i18next(options) ### Description Registers the i18next plugin with the Elysia application. This function initializes the translation instance and injects translation utilities into the request context. ### Parameters - **options** (I18NextPluginOptions) - Required - Configuration object for the plugin, including initOptions for i18next. ``` -------------------------------- ### Implement Database-Based Language Detection Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/examples.md Asynchronously retrieves user language preferences from a database based on an authenticated user ID. ```typescript import { LanguageDetector } from "elysia-i18next"; const dbDetector: LanguageDetector = async (ctx) => { // Assume auth middleware sets user in store const userId = (ctx.store as any).userId; if (!userId) return null; // Look up user's language preference const user = await database.users.findById(userId); return user?.preferredLanguage || null; }; new Elysia() .use(i18next({ detectLanguage: dbDetector, initOptions: { /* ... */ } })) .listen(3000); ``` -------------------------------- ### Configure and Test Language Detector Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Define detector search parameters and wrap the detector in a test function with logging to verify detection logic. ```typescript const detector = newLanguageDetector({ searchParamName: "lang", // Check ?lang=en storeParamName: "language", // Check store.language headerName: "accept-language", // Check header cookieName: "lang", // Check cookie pathParamName: "lang", // Check path param }); // Test with logging const testDetector: LanguageDetector = async (ctx) => { console.log("Detecting language..."); const lang = await detector(ctx); console.log("Detected:", lang); return lang; }; ``` -------------------------------- ### Implement a Custom Language Detector Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/advanced-usage.md Define an async function that accepts the Elysia context and returns a language code or null. ```typescript import { LanguageDetector } from "elysia-i18next"; const customDetector: LanguageDetector = async (ctx) => { // Your custom logic here return "en"; }; ``` -------------------------------- ### Implement Multilingual Routing Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/getting-started.md Uses the :lang path parameter to automatically detect and set the application language. ```typescript import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; new Elysia() .use( i18next({ initOptions: { lng: "en", supportedLngs: ["en", "de", "fr"], resources: { en: { translation: { greeting: "Hello" } }, de: { translation: { greeting: "Hallo" } }, fr: { translation: { greeting: "Bonjour" } }, }, }, }), ) .get("/:lang/greet", ({ t }) => t("greeting")) .listen(3000); // GET /en/greet → "Hello" // GET /de/greet → "Hallo" // GET /fr/greet → "Bonjour" ``` -------------------------------- ### Configure conditional translation loading Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/examples.md Dynamically provide resources to the i18next plugin based on environment variables or application state. ```typescript const loadTranslations = () => { if (process.env.DEMO_MODE === "true") { return { en: { translation: { greeting: "Hello (Demo)", }, }, }; } return { en: { translation: { greeting: "Hello", }, }, }; }; new Elysia() .use( i18next({ initOptions: { lng: "en", resources: loadTranslations(), }, }), ) .listen(3000); ``` -------------------------------- ### Use I18NextRequest in Route Handlers Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/types.md Demonstrates integrating the i18next plugin and accessing translation functions within an Elysia route handler. ```typescript import { Elysia, Context } from "elysia"; import { i18next, I18NextRequest } from "elysia-i18next"; new Elysia() .use( i18next({ initOptions: { lng: "en", resources: { en: { translation: { greeting: "Hello {{name}}", }, }, }, }, }), ) .get("/", ({ t, i18n }: Context & I18NextRequest) => { // Using t function const message = t("greeting", { name: "World" }); // Using i18n instance const currentLang = i18n.language; return { message, currentLang }; }) .listen(3000); ``` -------------------------------- ### Implement custom language negotiation Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/advanced-usage.md Define a custom detector to handle fallback logic when the requested language is unavailable. ```typescript const negotiateLanguage = (requested: string, supported: string[]): string => { // Exact match if (supported.includes(requested)) return requested; // Language code match (en-US → en) const base = requested.split("-")[0]; if (supported.includes(base)) return base; // Region fallback const inRegion = supported.find((l) => l.startsWith(base)); if (inRegion) return inRegion; // Default return supported[0]; }; const negotiatingDetector: LanguageDetector = (ctx) => { const requested = ctx.request.headers.get("accept-language"); if (!requested) return null; const supported = ["en", "en-US", "de", "de-DE", "fr"]; const negotiated = negotiateLanguage(requested, supported); return negotiated; }; new Elysia() .use(i18next({ detectLanguage: negotiatingDetector, /* ... */ })) .listen(3000); ``` -------------------------------- ### Default Configuration Object Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/configuration.md The default configuration applied when no options are provided to the i18next function. ```typescript { instance: null, // Uses global i18next instance initOptions: {}, // No resources, uses i18next defaults detectLanguage: newLanguageDetector({ searchParamName: 'lang', // Query param: ?lang=en storeParamName: 'language', // Store property: ctx.store.language headerName: 'accept-language', // HTTP header: Accept-Language cookieName: 'lang', // Cookie: lang=en pathParamName: 'lang', // Path param: /:lang/... }) } ``` -------------------------------- ### Configuring Custom Language Detection Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/getting-started.md Shows how to override default language detection using a pre-configured detector or a custom asynchronous function. ```typescript import { i18next, newLanguageDetector } from "elysia-i18next"; const detector = newLanguageDetector({ searchParamName: "locale", storeParamName: "userLanguage", headerName: "x-language", cookieName: "userLocale", pathParamName: "locale", }); new Elysia() .use( i18next({ detectLanguage: detector, initOptions: { /* ... */ }, }), ) .listen(3000); ``` ```typescript const myDetector = async (ctx) => { // Custom logic: check user in database if (ctx.store.userId) { const user = await db.users.findById(ctx.store.userId); return user.preferredLanguage; } return null; // Falls back to default }; new Elysia() .use( i18next({ detectLanguage: myDetector, initOptions: { /* ... */ }, }), ) .listen(3000); ``` -------------------------------- ### Register Global Derive Hook Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/module-structure.md Initializes i18next and injects the instance into the request context. ```typescript .derive({ as: 'global' }, async () => { const _instance = options.instance || lib if (!_instance.isInitialized) { await _instance.init(options.initOptions) } const _clone = _instance.cloneInstance() return { i18n: _clone, t: _clone.t } }) ``` -------------------------------- ### Import I18NextRequest Types Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Correctly import and apply I18NextRequest types to the Elysia context in handlers. ```typescript import type { I18NextRequest } from "elysia-i18next"; import { Context } from "elysia"; // Use in handler handler: (context: Context & I18NextRequest) => { /* ... */ } ``` -------------------------------- ### Test language detection via query parameters Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/examples.md Verifies that the plugin correctly detects the language from a 'lang' query parameter in the request URL. ```typescript it("detects language from query param", async () => { const i18n = createInstance({ lng: "en", resources: { en: { translation: { hi: "Hello" } }, de: { translation: { hi: "Hallo" } }, }, }); const app = new Elysia() .use(i18next({ instance: i18n })) .get("/", ({ t }) => t("hi")); const resDE = await app.handle(new Request("http://localhost/?lang=de")); expect(await resDE.text()).toBe("Hallo"); const resEN = await app.handle(new Request("http://localhost/?lang=en")); expect(await resEN.text()).toBe("Hello"); }); ``` -------------------------------- ### Database-Based Language Detection Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/advanced-usage.md Retrieve user language preferences from a database using context store data. ```typescript import { LanguageDetector } from "elysia-i18next"; import { i18next } from "elysia-i18next"; const dbDetector: LanguageDetector = async (ctx) => { // Assume store.userId is set by auth middleware if (!ctx.store.userId) { return null; // No user, use default } const user = await db.users.findById(ctx.store.userId); return user?.preferredLanguage || null; }; new Elysia() .use(i18next({ detectLanguage: dbDetector, initOptions: { /* ... */ } })) .listen(3000); ``` -------------------------------- ### Generate Multilingual Sitemap Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/examples.md Utilizes the i18n context to generate localized URLs for a sitemap. ```typescript .get("/sitemap.xml", ({ i18n }) => { const supportedLanguages = ["en", "de", "fr"]; const urls = supportedLanguages.map((lang) => ({ loc: `https://example.com/${lang}/`, language: lang, })); return { urls }; }) ``` -------------------------------- ### Monitoring Language Detection Performance Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/migration-guide.md Wraps a language detector to log warnings when detection exceeds 100ms. ```typescript const loggingDetector: LanguageDetector = async (ctx) => { const start = Date.now(); const lang = await detector(ctx); const duration = Date.now() - start; if (duration > 100) { console.warn("Slow language detection:", { lang, duration }); } return lang; }; ``` -------------------------------- ### Multiple Languages with Fallback Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/examples.md Configures complex fallback logic for specific language codes. ```typescript import { Elysia } from "elysia"; import { i18next } from "elysia-i18next"; new Elysia() .use( i18next({ initOptions: { lng: "en-US", fallbackLng: { "en-US": ["en"], "de-DE": ["de"], default: ["en"], }, resources: { en: { translation: { greeting: "Hello", farewell: "Goodbye", }, }, de: { translation: { greeting: "Hallo", farewell: "Auf Wiedersehen", }, }, fr: { translation: { greeting: "Bonjour", farewell: "Au revoir", }, }, }, }, }), ) .get("/", ({ t }) => ({ greeting: t("greeting") })) .get("/bye", ({ t }) => ({ message: t("farewell") })) .listen(3000); ``` -------------------------------- ### Extend Elysia Context with TypeScript Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/request-context.md Use global interface augmentation to provide IDE support for i18next properties within the Elysia context. ```typescript import { Elysia, Context } from "elysia"; import { i18next, I18NextRequest } from "elysia-i18next"; declare global { interface Context extends I18NextRequest {} } const app = new Elysia() .use( i18next({ initOptions: { lng: "en", resources: { en: { translation: { hi: "Hi" } } }, }, }), ) .get("/", ({ t }) => { // t is now recognized by TypeScript return { message: t("hi") }; }); ``` -------------------------------- ### Language Detection Priority Logic Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/language-detector.md Illustrates the evaluation order of the detector when multiple language indicators are present in a request. ```typescript const detector = newLanguageDetector({ searchParamName: "lang", storeParamName: "language", headerName: "accept-language", cookieName: "lang", pathParamName: "lang", }); // Request: GET /fr/page?lang=es // Cookie: lang=de // Store: language=it // Header: accept-language: pt // Priority evaluation: // 1. Check query param "lang" → found "es" ✓ STOPS HERE, returns "es" // 2. (Skipped) Cookie "lang" // 3. (Skipped) Path param "lang" // 4. (Skipped) Store property "language" // 5. (Skipped) Header "accept-language" ``` -------------------------------- ### Access i18n instance and translation function Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/api-reference/README.md Retrieve the current language, text direction, and translations from the request context. ```typescript .get("/info", ({ i18n, t }) => { return { currentLanguage: i18n.language, direction: i18n.dir(), message: t("greeting"), }; }) ``` -------------------------------- ### i18next() Source: https://github.com/eelkevdbos/elysia-i18next/blob/main/_autodocs/complete-reference.md Registers the i18next integration with an Elysia application, injecting i18n and t helpers into the request context. ```APIDOC ## i18next(userOptions) ### Description Registers i18next integration with Elysia. Clones the i18next instance per request for isolation. Detects language automatically and injects `i18n` and `t` into the request context. ### Parameters - **userOptions** (Partial) - Required - Partial plugin configuration, merged with defaults. ### Returns A function that accepts an Elysia instance and returns it with middleware applied. ### Example ```typescript new Elysia() .use( i18next({ initOptions: { lng: "en", resources: { /* ... */ } }, }), ) .get("/", ({ t }) => t("greeting")) .listen(3000); ``` ```