@sonardigital/translations
v1.1.3
Published
A tiny React/i18next helper that bootstraps i18n, provides a lightweight context, and exposes ergonomic hooks for app-wide translations and namespaced keys.
Readme
@sonardigital/translations
A tiny React/i18next helper that bootstraps i18n, provides a lightweight context, and exposes ergonomic hooks for app-wide translations and namespaced keys.
Installation
npm install @sonardigital/translations i18next react-i18next
# or
yarn add @sonardigital/translations i18next react-i18nextWhat this gives you
- Provider:
TranslationsWrapperto wire translations and language into context - Hooks:
useTranslationsto initialize i18n and expose{ t, i18n, changeLanguage, language }useTranslationsContextto read the shared context anywhereuseNamespaceT(namespace)to prefix keys likeCOMMONS.title
- Utilities:
initializeI18n(resources, lng)andcreateI18nInstance(language, resources)getDeviceLanguage()
- Constants:
DEFAULT_LANGUAGE,LANGUAGE_OPTIONS,LANGUAGE_STORAGE_KEY
Minimal example
import React from 'react';
import { createRoot } from 'react-dom/client';
import {
TranslationsWrapper,
useTranslationsContext,
useNamespaceT,
DEFAULT_LANGUAGE,
} from '@sonardigital/translations';
const resources = {
en: { translation: { hello: 'Hello', COMMONS: { title: 'Home' } } },
it: { translation: { hello: 'Ciao', COMMONS: { title: 'Home' } } },
};
function App() {
const { t, changeLanguage, language } = useTranslationsContext();
const tc = useNamespaceT('COMMONS');
return (
<div>
<h1>{tc('title')}</h1>
<p>{t('hello')}</p>
<button onClick={() => changeLanguage(language === 'en' ? 'it' : 'en')}>
Switch language
</button>
</div>
);
}
createRoot(document.getElementById('root')!).render(
<TranslationsWrapper language={DEFAULT_LANGUAGE} translations={resources}>
<App />
</TranslationsWrapper>
);API
TranslationsWrapperprops:- language?: string – initial language. If omitted, uses current i18next language
- translations:
Record<string, unknown>– i18next resources object{ [lng]: { translation: { ... } } } - methods?: return of
useTranslationsto override provided methods
useTranslations({ language?, translations })→{ t, i18n, changeLanguage, language }- Initializes i18n once with
initializeI18nand keeps language in sync
- Initializes i18n once with
useTranslationsContext()→ same shape as above, from contextuseNamespaceT(namespace: string)→(key: string, options?) => string- Returns a
tthat prefixes keys with${namespace}.
- Returns a
initializeI18n(resources, lng)- Sets up i18next with
react-i18next; default ns istranslation,useSuspense: false
- Sets up i18next with
createI18nInstance(language, resources)- Creates and returns a detached i18n instance (advanced/SSR)
getDeviceLanguage()- Returns browser language or
DEFAULT_LANGUAGE
- Returns browser language or
Constants:
DEFAULT_LANGUAGE = 'it',LANGUAGE_OPTIONS,LANGUAGE_STORAGE_KEY
Resource shape
const resources = {
en: {
translation: {
hello: 'Hello',
COMMONS: { title: 'Home' },
},
},
it: {
translation: {
hello: 'Ciao',
COMMONS: { title: 'Home' },
},
},
};Notes
- The library disables escaping in interpolation (
escapeValue: false) and disables React suspense in config. - If you already have i18next initialized, you can pass
methodstoTranslationsWrapperto reuse your instance and configuration.
License
ISC
