Skip to content

Repository files navigation

@wads.dev/i18n-react

Typed React bindings for translation catalogs built with @wads.dev/i18n-ts.

The package creates an isolated translation runtime containing a Provider and a selector-based hook. It also renders typed translation tokens as React nodes. It does not own project translations, storage or platform-specific locale detection.

Status: 0.0.1-alpha.0. Public APIs may change before 1.0.0.

Wads i18n ecosystem

Project Responsibility
@wads.dev/i18n-ts Framework-independent contracts, language loading, project configuration and portable bundles.
@wads.dev/i18n-react React Provider, hooks and rich translation rendering. This repository.
@wads.dev/i18n-editor Local editor for inspecting and changing bundles and, incrementally, regenerating project files.

React applications normally install i18n-ts and i18n-react. The Editor is an optional development tool and does not become part of the application runtime.

Installation

npm install @wads.dev/i18n-ts@alpha @wads.dev/i18n-react@alpha

React is a peer dependency. The minimum supported version is 16.8.0, where Hooks were introduced. The distributed JavaScript uses createElement rather than the newer automatic JSX runtime, so the package does not force a newer React version on consuming projects.

Create the project runtime

Keep the reusable package separate from the application's catalog and bootstrap behavior:

import { createTranslationRuntime } from '@wads.dev/i18n-react'
import type { AvailableLangs, Translation } from '@wads.dev/i18n-ts'

interface AppTranslation extends Translation {
  commons: {
    continue: string
  }
  cart: {
    itemCount: (count: number) => string
  }
}

type AppLanguage = 'en' | 'pt'

const languages = {
  en: {
    name: 'English',
    short: 'EN',
    locale: 'en-US',
    lang: () => import('./translations/en.js'),
  },
  pt: {
    name: 'Português',
    short: 'PT',
    locale: 'pt-BR',
    lang: () => import('./translations/pt.js'),
  },
} satisfies AvailableLangs<AppLanguage, AppTranslation>

export const { TranslationProvider, useTranslation } =
  createTranslationRuntime<AppLanguage, AppTranslation>({
    availableLangs: languages,
    defaultLang: 'en',
    onLanguageLoaded: (language) => {
      console.info(`Loaded ${language.locale}`)
    },
  })

Render the Provider at the application boundary:

<TranslationProvider>
  <App />
</TranslationProvider>

Read translations

Select the smallest useful scope:

const { scoped: cart } = useTranslation((translation) => translation.cart)

cart.itemCount(3)

Calling the hook without a selector returns the complete deeply readonly translation tree:

const { scoped: translation, current, available, saved, setLanguage } = useTranslation()

useTranslation throws a descriptive error when called outside its matching Provider.

Change language

const { setLanguage } = useTranslation()

setLanguage('pt', true)

Passing undefined asks @wads.dev/i18n-ts to select from the environment locale and configured default. The current alpha keeps the selected value in Provider state; persistence is intentionally the consuming application's responsibility.

Render typed tokens

withRender turns a %token% template into a typed renderable translation:

import { withRender } from '@wads.dev/i18n-react'

const terms = withRender(
  'I accept the %terms% and %privacy%.',
  {
    terms: 'Terms of Use',
    privacy: 'Privacy Policy',
  },
  {
    terms: (text) => <a href="/terms">{text}</a>,
    privacy: (text) => <a href="/privacy">{text}</a>,
  },
)

Token names are inferred from the provided record and remain compatible with the TranslationRender contract from @wads.dev/i18n-ts.

Multiple runtimes

Every call to createTranslationRuntime creates a distinct React Context. Independent applications, previews or embedded trees can therefore use different catalogs without a global singleton.

Public API

  • createTranslationRuntime(options) — creates a typed Provider and hook.
  • withRender(template, tokens, renders?) — creates typed rich/tokenized text.
  • CreateTranslationRuntimeOptions — runtime factory options.
  • TranslationRuntime — factory result.
  • TranslationContext, TranslationSelector and UseTranslationResult — integration types.

Package boundaries

  • Translation contracts and language loading belong to @wads.dev/i18n-ts.
  • React Context, hooks and React-node rendering belong here.
  • Catalog composition, selected-language persistence and application bootstrap remain in the consuming project.
  • Bundle editing and source-file generation belong to @wads.dev/i18n-editor.

Development

npm install
npm run check
npm run build
npm pack --dry-run

The package publishes ESM JavaScript and TypeScript declarations from dist/.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages