npm package: @meursyphus/i18n-llm
Description: LLM-friendly Next.js i18n library with type-safe translations
Author: meursyphus
Latest version: 0.1.0

# i18n-llm

LLM-friendly Next.js i18n library with type-safe translations.

## Features

- **LLM-readable documentation**: Copy-paste `llm.txt` to 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`, `/ko` prefixes needed)

## Installation

```bash
npm install @meursyphus/i18n-llm
```

## Quick Start

### 1. Initialize (CLI)

```bash
npx i18n-llm init --locales en,ko --default en
```

Or follow the manual setup in [llm.txt](./llm.txt).

### 2. Wrap your app

```tsx
// 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:**
```tsx
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:**
```tsx
'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

```typescript
import { defineI18nConfig } from '@meursyphus/i18n-llm';

export default defineI18nConfig({
  defaultLocale: 'en',
  locales: ['en', 'ko', 'ja'] as const,
  messagesPath: './messages',
});
```

### middleware.ts

```typescript
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 translations
```

### Type Definition

```typescript
// messages/types.ts
export interface Messages {
  common: {
    title: string;
    greeting: string;  // "Hello, {name}!"
    nav: {
      home: string;
      about: string;
    };
  };
}
```

### Translation File

```typescript
// 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:

```typescript
// Message
"greeting": "Hello, {name}! You have {count} messages."

// Usage
t('greeting', { name: 'John', count: 5 });
// Output: "Hello, John! You have 5 messages."
```

## Language Switcher

```tsx
'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

```bash
# 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](./llm.txt) to your AI assistant.

## License

MIT