nativtongue
v0.0.5
Published
Zero boilerplate i18n for React
Maintainers
Readme
nativtongue
Zero boilerplate i18n for React. Just write your UI — translations happen automatically.
Install
npm install nativtongueUsage
Wrap your app with TranslationProvider:
import { TranslationProvider } from 'nativtongue'
function App() {
return (
<TranslationProvider defaultLocale="en">
<h1>Welcome to my app</h1>
<p>This text is translated automatically.</p>
<button aria-label="Submit form">Submit</button>
<input placeholder="Search..." />
</TranslationProvider>
)
}That's it. All text content and translatable attributes (aria-label, placeholder, title, alt) are translated automatically via DOM walking. No wrappers, no function calls.
How it works
TranslationProviderloads a JSON translation file for the active locale (e.g./i18n/fr.json)- A DOM TreeWalker finds every text node and translatable attribute inside the provider
- Each string is looked up in the translation map and replaced
- A MutationObserver watches for dynamically added content and translates it on the fly
- A WeakMap stores original text per node so switching back to the source language works correctly
Translation files
Translation files are flat JSON objects mapping source strings to translated strings:
{
"Welcome to my app": "Bienvenue sur mon application",
"This text is translated automatically.": "Ce texte est traduit automatiquement.",
"Submit": "Envoyer",
"Submit form": "Envoyer le formulaire",
"Search...": "Rechercher..."
}Use nativtongue-cli to generate and auto-translate these files.
API
<TranslationProvider>
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| defaultLocale | string | 'en' | Initial locale (uncontrolled mode) |
| locale | string | — | Controlled locale (parent drives changes) |
| sourceLocale | string | 'en' | The language your source code is written in |
| fetch | (locale: string) => Promise<Response> | fetch(\/i18n/${locale}.json`)| Custom translation file loader |
|fallback|ReactNode|null| Shown while translations are loading |
|onMissing|(key: string, locale: string) => void` | — | Called when a translation key is not found |
useTranslation()
Access locale and switch languages from any component inside the provider:
const { locale, setLocale } = useTranslation()<TranslationScope>
Disambiguate identical strings that need different translations depending on context:
<TranslationScope context="navigation">
<p>Back</p> {/* looks up "navigation::Back" */}
</TranslationScope>
<TranslationScope context="body">
<p>Back</p> {/* looks up "body::Back" */}
</TranslationScope>
<p>Back</p> {/* looks up "Back" */}useT()
Escape hatch for when you need a translated string as a JavaScript value (not in the DOM):
const t = useT()
document.title = t('My App')