npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@liberfi.io/i18n

v0.1.94

Published

Internationalization for Liberfi React SDK

Downloads

10,104

Readme

@liberfi.io/i18n

Internationalization and CLI tools for Liberfi React SDK. Built on the i18next ecosystem, this package provides locale management, language detection, async resource loading, and CLI tools for translation workflows. Consumed by @liberfi.io/react-app and downstream apps.

Design Philosophy

  • Inversion of Control — Side effects (e.g. language-change callbacks, resource loading URLs) are injected via props/options rather than hardcoded. The Backend class receives its i18n instance via constructor injection for testability.
  • Provider-optional — The package exports a singleton i18n instance with sensible defaults (English fallback). Components work without LocaleProvider; the provider adds resource loading, language switching callbacks, and context-based configuration.
  • Separation of concerns — Pure utility functions (parseI18nLang, removeLangPrefix, etc.) live in utils/ with no dependencies on React or i18n state, making them usable in both client and server contexts.
  • Single source of truth — All locale types, enums, and default language data are defined once in types.ts and constant.ts, shared across client and server entry points.

Installation

pnpm add @liberfi.io/i18n

Peer dependencies: react >= 18, react-dom >= 18.

API Reference

Components

| Component | Props | Description | | ---------------- | --------------------- | -------------------------------------------------------------------------------------------------------------- | | LocaleProvider | LocaleProviderProps | Wraps the app with i18next context, manages resource loading, language detection, and exposes LocaleContext. |

LocaleProviderProps:

| Prop | Type | Description | | ------------------------- | ------------------------------------- | ------------------------------------------------------------ | | locale | LocaleCode | Current locale to force. | | resource | Record<string, string> | Resource bundle for the current locale. | | resources | Resources | All synchronously loaded resources keyed by locale. | | supportedLanguages | LocaleCode[] | Subset of defaultLanguages to expose. | | convertDetectedLanguage | (lang: string) => LocaleCode | Custom conversion for the detected browser language. | | backend | BackendOptions | Options for async resource loading via HTTP (loadPath). | | languages | Language[] | Fully custom language list (overrides supportedLanguages). | | beforeLanguageChange | (lang: LocaleCode) => Promise<void> | Called before language switch (e.g. load resources). | | afterLanguageChange | (lang: LocaleCode) => Promise<void> | Called after language switch (e.g. update cookie/URL). |

Hooks

| Hook | Return | Description | | ------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | useTranslation(ns?, options?) | UseTranslationResponse | Wraps react-i18next's useTranslation, auto-falls back to the singleton i18n instance when used outside I18nextProvider. | | useLocale() | LocaleCode | Returns the current locale code and re-renders on language change. | | useChangeLocale() | (locale: LocaleCode) => Promise<void> | Returns a function that triggers beforeLanguageChangei18n.changeLanguageafterLanguageChange. | | useLocaleContext() | LocaleContextState | Access languages, beforeLanguageChange, afterLanguageChange from context. |

Utilities

| Function | Signature | Description | | --------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | | parseI18nLang | (lang: string, localeCodes?: LocaleCode[], defaultLang?: LocaleCode) => string | Normalize a browser language string (e.g. en-US) to a supported locale code. | | getLocalePathFromPathname | (pathname: string, localeCodes?: string[]) => string \| null | Extract the locale segment from a URL pathname (e.g. /en/markets"en"). | | removeLangPrefix | (pathname: string, localeCodes?: string[]) => string | Strip the locale prefix from a pathname. | | generatePath | (params: { path: string; locale?: string; search?: string }) => string | Build a localized URL path with locale prefix and search params. |

Types & Enums

| Export | Description | | ---------------------- | --------------------------------------------------------------------------------- | | LocaleEnum | Enum of all 16 supported locale codes. | | LocaleCode | keyof typeof LocaleEnum \| (string & {}) — locale code type allowing extension. | | Language | { localCode: LocaleCode; displayName: string } | | Resources<T> | Map of LocaleCode → partial locale messages, optionally extended with T. | | LocaleMessages | Full English message type merged with ExtendLocaleMessages. | | ExtendLocaleMessages | Record<"extend.${string}", string> — type for custom extension keys. | | BackendOptions | { loadPath: (lang, ns) => string \| string[] } | | LocaleContextState | Context shape: languages, beforeLanguageChange, afterLanguageChange. |

Constants

| Export | Value | Description | | --------------------- | ------------------------ | ---------------------------------------------- | | defaultLanguages | Language[] | All 16 supported languages with display names. | | defaultLng | "en" | Default fallback language. | | defaultNS | "translation" | Default i18next namespace. | | i18nLocalStorageKey | "liberfi_i18nLng" | localStorage key for persisted language. | | i18nCookieKey | "liberfi_i18nLng" | Cookie key for persisted language. | | en | Record<string, string> | Built-in English translations. |

Integration Guide

Follow these steps to integrate localization support in your app using Liberfi React SDK:

1. Wrap Your App with LocaleProvider

The LocaleProvider is the core component that supplies localized resources to your application. Make sure to wrap your app’s root component with LocaleProvider.

import { LocaleProvider } from "@liberfi.io/i18n";

<LocaleProvider>
  <YourApp />
</LocaleProvider>;

2. Provide Locale Data

Default Language

  • English (en) is included by default.

Supported Locales

We currently support 16 locales

| Locale Code | Language | | ----------- | ---------- | | en | English | | zh | Chinese | | ja | Japanese | | es | Spanish | | ko | Korean | | vi | Vietnamese | | de | German | | fr | French | | ru | Russian | | id | Indonesian | | tr | Turkish | | it | Italian | | pt | Portuguese | | uk | Ukrainian | | pl | Polish | | nl | Dutch |

CSV for Easy Translation

  • Each release generates a dist/locale.csv file to simplify translation workflows.
  • We provide a CLI tool to convert between CSV and JSON formats.

3. Extending Locale Files

You can localize both the SDK UI and your own custom components.

  • When adding custom keys, prefix them with extend. to avoid conflicts with default keys.
{
  "extend.custom.button.label": "My Custom Button"
}

Example

Here's a complete example of how to set up the i18n integration:

Async load locale files

import { FC, ReactNode } from "react";
import { WalletConnectorProvider } from "@liberfi.io/wallet-connector";
import { LiberfiAppProvider } from "@liberfi.io/react-app";
import { LocaleProvider, LocaleEnum, LocaleCode } from "@liberfi.io/i18n";

const LiberfiProvider: FC<{ children: ReactNode }> = (props) => {
  const onLanguageChanged = async (lang: LocaleCode) => {};

  // please copy build-in locale files (@liberfi.io/i18n/locales) to you public/locales
  // and copy you extend locale files to public/locales/extend
  const loadPath = (lang: LocaleCode) => {
    if (lang === LocaleEnum.en) {
      // because en is built-in, we need to load the en extend only
      return `/locales/extend/${lang}.json`;
    }
    return [`/locales/${lang}.json`, `/locales/extend/${lang}.json`];
  };

  return (
    <LocaleProvider
      onLanguageChanged={onLanguageChanged}
      backend={{ loadPath }}
    >
      <WalletConnectorProvider>
        <LiberfiAppProvider
          brokerId="liberfi"
          brokerName="Liberfi"
          networkId="testnet"
        >
          {props.children}
        </LiberfiAppProvider>
      </WalletConnectorProvider>
    </LocaleProvider>
  );
};

Sync Load locale data

import { FC, ReactNode } from "react";
import { WalletConnectorProvider } from "@liberfi.io/wallet-connector";
import { LiberfiAppProvider } from "@liberfi.io/react-app";
import { LocaleProvider, LocaleCode, Resources } from "@liberfi.io/i18n";
import zh from "@liberfi.io/i18n/locales/zh.json";
import ja from "@liberfi.io/i18n/locales/ja.json";
import ko from "@liberfi.io/i18n/locales/ko.json";

// extend or overrides English translations
const extendEn = {
  "extend.trading": "Trading",
};

// extend or overrides chinese translations
const extendZh = {
  "extend.trading": "交易",
};

// extend or overrides japanese translations
const extendJa = {
  "extend.trading": "取引",
};

// extend or overrides korean translations
const extendKo = {
  "extend.trading": "거래",
};

// define language resources
const resources: Resources = {
  en: extendEn,
  zh: {
    ...zh,
    ...extendZh,
  },
  ja: {
    ...ja,
    ...extendJa,
  },
  ko: {
    ...ko,
    ...extendKo,
  },
};

const LiberfiProvider: FC<{ children: ReactNode }> = (props) => {
  const onLanguageChanged = (locale: LocaleCode) => {};

  return (
    <LocaleProvider resources={resources} onLanguageChanged={onLocaleChange}>
      <WalletConnectorProvider>
        <LiberfiAppProvider
          brokerId="liberfi"
          brokerName="Liberfi"
          networkId="testnet"
        >
          {props.children}
        </LiberfiAppProvider>
      </WalletConnectorProvider>
    </LocaleProvider>
  );
};

Add custom languages

We also support adding more custom languages

import { FC, ReactNode } from "react";
import { WalletConnectorProvider } from "@liberfi.io/wallet-connector";
import { LiberfiAppProvider } from "@liberfi.io/react-app";
import {
  LocaleProvider,
  Resources,
  LocaleEnum,
  LocaleCode,
  Language,
} from "@liberfi.io/i18n";

// japanese locale
const ja = {
  "extend.ja": "日本語",
};

// korean locale
const ko = {
  "extend.ko": "한국어",
};

// define language resources
const resources: Resources = {
  ja,
  ko,
};

// custom languages
const languages: Language[] = [
  { localCode: LocaleEnum.en, displayName: "English" },
  { localCode: LocaleEnum.ja, displayName: "日本語" },
  { localCode: LocaleEnum.ko, displayName: "한국어" },
];

const LiberfiProvider: FC<{ children: ReactNode }> = (props) => {
  const onLanguageChanged = (locale: LocaleCode) => {};

  return (
    <LocaleProvider
      resources={resources}
      languages={languages}
      onLanguageChanged={onLanguageChanged}
    >
      <WalletConnectorProvider>
        <LiberfiAppProvider
          brokerId="liberfi"
          brokerName="Liberfi"
          networkId="testnet"
        >
          {props.children}
        </LiberfiAppProvider>
      </WalletConnectorProvider>
    </LocaleProvider>
  );
};

CLI

Usage

The package provides a CLI tool for managing Internationalization files.

npx @liberfi.io/i18n <command> [options]

Commands

csv2json

Convert a locale CSV file to multiple locale JSON files.

npx @liberfi.io/i18n csv2json <input> <outputDir>

Example:

npx @liberfi.io/i18n csv2json ./dist/locale.csv ./dist/locales

json2csv

Convert multiple locale JSON files to a single locale CSV file.

npx @liberfi.io/i18n json2csv <inputDir> <output>

Example:

npx @liberfi.io/i18n json2csv ./locales ./dist/locale.csv

diffcsv

Compare two locale CSV files to find differences.

npx @liberfi.io/i18n diffcsv <oldFile> <newFile>

Example:

npx @liberfi.io/i18n diffcsv ./dist/locale1.csv ./dist/locale2.csv

fillJson

Fill values from an input locale JSON file and generate a new locale JSON file.

npx @liberfi.io/i18n fillJson <input> <output>

Example:

npx @liberfi.io/i18n fillJson ./src/locale/zh.json ./dist/locale/zh.json

separateJson

Separate JSON files into default and extend key values based on a specified key.

npx @liberfi.io/i18n separateJson <inputDir> <outputDir> <separateKey>

Example:

npx @liberfi.io/i18n separateJson ./locales ./dist/locales extend

mergeJson

Merge default and extend JSON files back into one file.

npx @liberfi.io/i18n mergeJson <inputDir> <outputDir>

Example:

npx @liberfi.io/i18n mergeJson ./dist/locales1 ./dist/locales2

Testing

Run unit tests:

pnpm test

Tests cover:

  • Utility functionsparseI18nLang, getLocalePathFromPathname, removeLangPrefix, generatePath
  • Backend class — async resource fetching, caching, error handling
  • React hooksuseLocale, useChangeLocale lifecycle and state updates
  • LocaleProvider — rendering, resource injection, language switching, context propagation

Future Improvements

  • Accept an i18n instance prop on LocaleProvider instead of relying on the module-level singleton, enabling multiple isolated i18n contexts.
  • Add onError callback to BackendOptions for caller-controlled error handling instead of console.warn.
  • Expose loading/error state from Backend so consumers can show loading indicators.
  • Consider lazy-loading locale modules to reduce initial bundle size for apps that only need a subset of languages.