i18nexus
v3.4.1
Published
Type-safe React i18n toolkit with intelligent automation and SSR support
Maintainers
Readme
🌐 i18nexus
Type-safe i18n for React with zero runtime overhead
✨ Features
🔒 Full Type Safety
- Auto-completion for translation keys
- Compile-time validation for translation keys and variables
- Type inference without explicit generics
- Interpolation variable type checking
⚡ Modern React Support
- Next.js 14+ App Router support
- Server Components translation
- Client Components translation
- React Server Actions support
🌍 Flexible Namespace Management
- Page-based translation file organization
- Component-based translation management
- Dynamic namespace loading
- Fallback namespace support
🎯 Developer Friendly
- Zero configuration for quick start
- Intuitive API design
- Comprehensive TypeScript types
- Rich documentation and examples
🔥 Performance Optimized
- Lightweight bundle size
- Lazy loading support
- Efficient memory usage
- Hot Module Replacement support
📦 Installation
npm install i18nexus
# or
yarn add i18nexus
# or
pnpm add i18nexus🚀 Quick Start
1. Create Translation Files
Create translation files in locales/[namespace]/[lang].json:
locales/
├── common/
│ ├── en.json
│ └── ko.json
└── home/
├── en.json
└── ko.json// locales/common/en.json
{
"welcome": "Welcome",
"hello": "Hello, {{name}}"
}// locales/common/ko.json
{
"welcome": "환영합니다",
"hello": "안녕하세요, {{name}}님"
}2. Setup Provider
For Next.js App Router, add Provider to your root layout:
// app/layout.tsx
import { I18nProvider } from "i18nexus";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html>
<body>
<I18nProvider initialLanguage="en">{children}</I18nProvider>
</body>
</html>
);
}3. Use in Components
Client Component
"use client";
import { useTranslation } from "i18nexus";
export default function Welcome() {
const { t } = useTranslation("common");
return (
<div>
<h1>{t("welcome")}</h1>
<p>{t("hello", { name: "John" })}</p>
</div>
);
}Server Component
import { getTranslation } from "i18nexus/server";
export default async function WelcomeServer() {
const { t } = await getTranslation("common");
return (
<div>
<h1>{t("welcome")}</h1>
<p>{t("hello", { name: "John" })}</p>
</div>
);
}📖 API Reference
useTranslation(namespace)
Hook for using translations in Client Components.
Parameters:
namespace(string): The namespace to load translations from
Returns:
t(key, variables?, styles?)- Translation functioncurrentLanguage(orlng) - Current language codeisReady- Whether translations are loaded
Example:
const { t, currentLanguage, isReady } = useTranslation("home");
// Basic usage
t("title"); // ✅ Type-safe
// With variables
t("greeting", { name: "Alice" }); // ✅ Type-safe
// With styles (returns ReactElement)
t("styled", {}, { bold: { fontWeight: "bold" } });getTranslation(namespace)
Function for getting translations in Server Components.
Parameters:
namespace(string): The namespace to load translations from
Returns:
t(key, variables?, styles?)- Translation functionlanguage(orlng) - Current language code
Example:
const { t, language } = await getTranslation("home");
console.log(language); // "en" or "ko"
t("title"); // ✅ Type-safeuseLanguageSwitcher()
Hook for language switching functionality.
Returns:
currentLanguage- Current language codechangeLanguage(lang)- Function to change languageavailableLanguages- List of available languages
Example:
"use client";
import { useLanguageSwitcher } from "i18nexus";
export function LanguageSwitcher() {
const { currentLanguage, changeLanguage, availableLanguages } =
useLanguageSwitcher();
return (
<select
value={currentLanguage}
onChange={(e) => changeLanguage(e.target.value)}
>
{availableLanguages.map((lang) => (
<option key={lang} value={lang}>
{lang.toUpperCase()}
</option>
))}
</select>
);
}🎨 Advanced Usage
Namespace Organization
Organize translation files by page or feature:
locales/
├── common/ # Shared translations
│ ├── en.json
│ └── ko.json
├── constant/ # Constant values (dropdowns, labels)
│ ├── en.json
│ └── ko.json
└── home/ # Page-specific translations
├── en.json
└── ko.jsonType-Safe Constants
Use namespace-specific types for type-safe constants:
import { useTranslation } from "i18nexus";
import type { ConstantKeys } from "@/locales/types/i18nexus";
const CATEGORY_OPTIONS: ConstantKeys[] = [
"category.all",
"category.tech",
"category.design",
];
function CategoryDropdown() {
const { t } = useTranslation("constant");
return (
<select>
{CATEGORY_OPTIONS.map((key) => (
<option key={key} value={key}>
{t(key)} {/* ✅ Type-safe */}
</option>
))}
</select>
);
}Dynamic Keys
For dynamic keys, explicitly type them as ConstantKeys:
import type { ConstantKeys } from "@/locales/types/i18nexus";
function DynamicLabel({ labelKey }: { labelKey: string }) {
const { t } = useTranslation("constant");
// Cast dynamic key to ConstantKeys
return <span>{t(labelKey as ConstantKeys)}</span>;
}Passing t as Props
When passing t as a prop, it automatically defaults to the common namespace:
// Parent component
function ParentComponent() {
const { t } = useTranslation("common"); // Explicit namespace
return <ChildComponent t={t} />;
}
// Child component
function ChildComponent({ t }: { t: (key: string) => string }) {
return <p>{t("welcome")}</p>; // ✅ Uses common namespace
}Styled Translations
Apply inline styles to parts of translated text:
// Translation file
{
"terms": "I agree to the <bold>Terms</bold> and <link>Privacy Policy</link>"
}
// Component
const { t } = useTranslation("legal");
const styledText = t("terms", {}, {
bold: { fontWeight: "bold" },
link: { color: "blue", textDecoration: "underline" }
});
return <div>{styledText}</div>; // Returns ReactElementVariable Interpolation
TypeScript validates required variables:
// Translation file
{
"greeting": "Hello, {{name}}!",
"stats": "You have {{count}} new messages"
}
// Component
const { t } = useTranslation("messages");
t("greeting", { name: "Alice" }); // ✅ OK
t("greeting"); // ❌ TypeScript error: 'name' is required
t("stats", { count: 5 }); // ✅ OK
t("stats", { total: 5 }); // ❌ TypeScript error: 'count' is required⚙️ Configuration
i18nexus.config.json
Create a configuration file in your project root:
{
"sourcePattern": "src/**/*.{ts,tsx}",
"translationImportSource": "i18nexus",
"languages": ["en", "ko"],
"defaultLanguage": "en",
"localesDir": "./locales",
"fallbackNamespace": ["common", "constant"]
}Options:
sourcePattern- Pattern for source files to extract translations fromtranslationImportSource- Import path for translation hooks (e.g.,"i18nexus","@/app/i18n/client")languages- List of supported languagesdefaultLanguage- Default languagelocalesDir- Directory for translation filesfallbackNamespace- Namespaces to load by default
🛠️ CLI Tools
i18nexus works seamlessly with i18nexus-tools for automation:
# Install CLI tools
npm install -D i18nexus-tools
# Extract translation keys from code
npx i18n-extractor
# Upload translations to Google Sheets
npx i18n-upload
# Download translations from Google Sheets
npx i18n-download
# Auto-wrap hardcoded text with t()
npx i18n-wrapperLearn more in the i18nexus-tools documentation.
🔗 Links
🧪 Testing
# Run tests
npm test
# Watch mode
npm run test:watch
# Coverage report
npm test -- --coverage🤝 Contributing
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please read CONTRIBUTING.md for details on our code of conduct and development process.
📄 License
MIT License - see the LICENSE file for details.
🙏 Acknowledgments
This project was inspired by excellent i18n libraries:
📈 Version History
v3.3.0 (Latest)
- ✨ Type inference improvements - no explicit generics needed
- 🔄 Wrapper removes redundant generic types
- 📚 Documentation updates
v3.2.0
- ✨ Namespace-specific type exports (
ConstantKeys,CommonKeys, etc.) - 🎯 Auto-default to
commonnamespace whentis passed as props - 📚 Enhanced TypeScript support
v3.1.0
- 🔒 Stricter type checking for dynamic keys
- 🎨 Function overloads for styled translations
- ⚡ Performance improvements
v3.0.0
- 🌍 Google Sheets formula escaping
- 📦 Namespace-based sheet organization
- 🛠️ CLI tool improvements
See CHANGELOG.md for full version history.
Made with ❤️ by the i18nexus team
