@meursyphus/i18n-llm
v0.1.0
Published
LLM-friendly Next.js i18n library with type-safe translations
Readme
i18n-llm
LLM-friendly Next.js i18n library with type-safe translations.
Features
- LLM-readable documentation: Copy-paste
llm.txtto set up i18n instantly - Type-safe translations: Full TypeScript support with key autocomplete
- Variable interpolation:
t("greeting", { name: "John" }) - Zero dependencies: Only requires Next.js and React
- App Router only: Built specifically for Next.js 14+ App Router
- Server & Client components: Works seamlessly in both
- No URL routing: Language managed via cookies (no
/en,/koprefixes needed)
Installation
npm install @meursyphus/i18n-llmQuick Start
1. Initialize (CLI)
npx i18n-llm init --locales en,ko --default enOr follow the manual setup in llm.txt.
2. Wrap your app
// app/layout.tsx
import { TranslationsProvider, getLocale } from '@meursyphus/i18n-llm';
export default async function RootLayout({ children }) {
const locale = await getLocale();
return (
<html lang={locale}>
<body>
<TranslationsProvider>
{children}
</TranslationsProvider>
</body>
</html>
);
}3. Use translations
Server Component:
import { getTranslations } from '@meursyphus/i18n-llm';
export default async function Page() {
const t = await getTranslations('common');
return <h1>{t('greeting', { name: 'World' })}</h1>;
}Client Component:
'use client';
import { useTranslations } from '@meursyphus/i18n-llm/client';
export function Greeting({ name }) {
const t = useTranslations('common');
return <p>{t('greeting', { name })}</p>;
}API Reference
Server Exports (@meursyphus/i18n-llm)
| Export | Description |
|--------|-------------|
| getTranslations(namespace) | Get translation function for server components |
| TranslationsProvider | Provider component for client components |
| getLocale() | Get current locale from cookie/header |
| defineI18nConfig(config) | Define i18n configuration |
Client Exports (@meursyphus/i18n-llm/client)
| Export | Description |
|--------|-------------|
| useTranslations(namespace) | Hook to get translation function |
| useCurrentLanguage() | Hook to get current locale |
| useSetLanguage() | Hook to change current language |
Middleware (@meursyphus/i18n-llm/middleware)
| Export | Description |
|--------|-------------|
| defineMiddleware(config) | Configure i18n middleware |
| middleware | The middleware function to export |
Actions (@meursyphus/i18n-llm/actions)
| Export | Description |
|--------|-------------|
| setLanguagePreference(locale) | Server action to change language |
| getLanguagePreference() | Get stored language preference |
Configuration
i18n.config.ts
import { defineI18nConfig } from '@meursyphus/i18n-llm';
export default defineI18nConfig({
defaultLocale: 'en',
locales: ['en', 'ko', 'ja'] as const,
messagesPath: './messages',
});middleware.ts
import { defineMiddleware, middleware } from '@meursyphus/i18n-llm/middleware';
defineMiddleware({
locales: ['en', 'ko', 'ja'],
defaultLocale: 'en',
});
export { middleware };
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico|.*\\..*).*)'],
};Message Files
Structure
messages/
├── types.ts # Type definitions
├── en/
│ └── index.ts # English translations
├── ko/
│ └── index.ts # Korean translations
└── ja/
└── index.ts # Japanese translationsType Definition
// messages/types.ts
export interface Messages {
common: {
title: string;
greeting: string; // "Hello, {name}!"
nav: {
home: string;
about: string;
};
};
}Translation File
// messages/en/index.ts
import type { Messages } from '../types';
const messages: Messages = {
common: {
title: 'Welcome',
greeting: 'Hello, {name}!',
nav: {
home: 'Home',
about: 'About',
},
},
};
export default messages;Variable Interpolation
Use {variableName} placeholders in your translations:
// Message
"greeting": "Hello, {name}! You have {count} messages."
// Usage
t('greeting', { name: 'John', count: 5 });
// Output: "Hello, John! You have 5 messages."Language Switcher
'use client';
import { useCurrentLanguage, useSetLanguage } from '@meursyphus/i18n-llm/client';
export function LanguageSwitcher() {
const currentLang = useCurrentLanguage();
const setLanguage = useSetLanguage();
return (
<select value={currentLang} onChange={(e) => setLanguage(e.target.value)}>
<option value="en">English</option>
<option value="ko">한국어</option>
<option value="ja">日本語</option>
</select>
);
}CLI Commands
# Initialize i18n-llm in your project
npx i18n-llm init --locales en,ko --default en
# Add a new locale
npx i18n-llm add-locale ja --name "日本語"LLM Setup
For AI-assisted setup, copy the contents of llm.txt to your AI assistant.
License
MIT
