intexor
v1.0.0
Published
A lightweight React localization library with context and persistence.
Downloads
1
Maintainers
Readme
✨ intexor — tiny, pragmatic i18n for React
A compact React language context and localization helper that fixes two real annoyances with typical i18n setups: duplicate key mappings and bloated central translation files. Keep translations next to components, persist user language, and sync across tabs — with zero ceremony. 🎯
🔥 Why intexor exists — the problem it solves
- No duplicate keys — Traditional key-based systems often force you to define the same mapping twice (e.g.,
hello: "Hola"and thenhola: "Hello"). That’s confusing and error-prone. intexor uses the current language as the lookup key, so you declare each string once per component. ✅ - No giant translation files — Centralized files grow fast and become hard to maintain. With intexor, translations live next to the component that uses them, making code easier to read and refactor. 🧩
- Local-first workflow — Translate inline where the text is used. Perfect for small-to-medium apps, prototypes, or UI text that belongs with the component. ⚡
⚡ Quick Start
import React from "react";
import LanguageProvider, { Localized } from "intexor";
export default function App() {
return (
<LanguageProvider>
<header>
<Localized children={{ en: "Hello", fr: "Bonjour" }} />
</header>
</LanguageProvider>
);
}Change language programmatically:
import { useLanguage } from "intexor";
function Switcher() {
const { language, setLanguage } = useLanguage();
return (
<>
<div>Current: {language}</div>
<button onClick={() => setLanguage("en")}>English 🇬🇧</button>
<button onClick={() => setLanguage("es")}>Español 🇪🇸</button>
</>
);
}Custom storage key:
<LanguageProvider storageKey="myapp_lang">
<App />
</LanguageProvider>📝 Examples — both prop and children forms
Prop form (common and explicit)
<Localized children={{ en: "Hello", es: "Hola" }} />Children expression form (JSX-friendly)
<Localized>{ { en: "Hello", es: "Hola" } }</Localized>Rich content (React nodes)
<Localized children={{
en: <strong>Yes</strong>,
es: <em>Sí</em>
}} />All forms return the value for the current language and fall back to the default (en) when needed. Use whichever style reads best in your codebase. ✨
📚 API Reference
| Export | Type | What it does |
|---|---:|---|
| LanguageProvider | React.Component | Wrap your app; accepts storageKey?: string to change the localStorage key 🏷️ |
| useLanguage | () => { language: string; setLanguage: (lang: string) => void } | Read and update current language 🔁 |
| Localized | ({ children: Record<LanguageCode, ReactNode> }) => ReactNode | Render language-specific content with fallback 🧩 |
| DEFAULT_LANGUAGE | string | "en" (default fallback) 🛡️ |
| DEFAULT_STORAGE_KEY | string | "lang" (default localStorage key) 💾 |
| normalizeLanguage | (lang?: string|null) => string | Normalize regioned codes like fr-FR → fr 🔤 |
| getInitialLanguage | (storageKey?: string) => string | Read initial language from storage or navigator.language 🌐 |
Behavior highlights
- Initial resolution:
localStorage[storageKey]→navigator.language→"en". - Persistence:
setLanguagewrites tolocalStorage[storageKey]. - Cross-tab sync: listens for
storageevents on the configured key. - SSR safe: guarded access to
windowandnavigator. - Fallback:
Localizedfalls back toDEFAULT_LANGUAGEwhen a key is missing.
🧪 Testing tips & migration notes
- Clear the same
storageKeyinbeforeEach. - Stub
navigator.languagefor deterministic tests. - Simulate cross-tab updates by dispatching a
storageevent and usewaitForto assert updates. - Migrate incrementally: replace a few components first, keep centralized i18n for complex needs. 🔀
🎉 Final note — tiny but mighty
intexor is built for clarity and speed: no duplicate keys, no bloated translation files, and translations that live where they belong — inside the component. Fast to adopt, easy to reason about, and delightfully simple. Try it in a feature or two and feel the difference. 🚀
