npm package: @ravshansbox/react-i18n
Description: A minimal, type-safe React i18n library with zero dependencies
Author: Ravshan
Latest version: 0.6.2

# @ravshansbox/react-i18n

A minimal, type-safe React i18n library with zero dependencies.

[![npm version](https://badge.fury.io/js/@ravshansbox%2Freact-i18n.svg)](https://badge.fury.io/js/@ravshansbox%2Freact-i18n)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

- 🚀 **Zero dependencies** - Lightweight and fast
- 🔒 **Type-safe** - Full TypeScript support with auto-completion
- 🎯 **Minimal API** - Simple and intuitive to use
- 🔄 **Parameter interpolation** - Support for dynamic values in translations
- 🌳 **Nested translations** - Organize your translations hierarchically
- ⚡ **React 18+ compatible** - Uses `useSyncExternalStore` for optimal performance

## Installation

```bash
npm install @ravshansbox/react-i18n
```

## Quick Start

### 1. Create translation files

**translations/en.json**

```json
{
  "greeting": "Hello",
  "welcome": "Welcome, {{name}}!",
  "messages": {
    "success": "Operation successful!",
    "error": "Something went wrong"
  }
}
```

**translations/tr.json**

```json
{
  "greeting": "Merhaba",
  "welcome": "Hoşgeldiniz, {{name}}!",
  "messages": {
    "success": "İşlem başarılı!",
    "error": "Bir şeyler ters gitti"
  }
}
```

### 2. Create an i18n instance

```typescript
import { createInstance } from '@ravshansbox/react-i18n'
import en from './translations/en.json'
import tr from './translations/tr.json'

const { useTranslation } = createInstance({
  supportedLanguages: ['en', 'tr'],
  defaultLanguage: 'en',
  translations: { en, tr },
})

export { useTranslation }
```

### 3. Use in your React components

```typescript
import React from 'react'
import { useTranslation } from './i18n'

function App() {
  const { t, language, setLanguage, supportedLanguages } = useTranslation()

  return (
    <div>
      <h1>{t('greeting')}</h1>
      <p>{t('welcome', { name: 'John' })}</p>
      <p>{t('messages.success')}</p>

      <select
        value={language}
        onChange={e => setLanguage(e.target.value as any)}
      >
        {supportedLanguages.map(lang => (
          <option key={lang} value={lang}>
            {lang}
          </option>
        ))}
      </select>
    </div>
  )
}
```

## API Reference

### `createInstance(config)`

Creates an i18n instance with the provided configuration.

#### Parameters

- `config.supportedLanguages`: Array of supported language codes
- `config.defaultLanguage`: Default language code (must be in supportedLanguages)
- `config.translations`: Translation object with nested structure

#### Returns

An object containing:

- `useTranslation`: React hook for accessing translation functionality

### `useTranslation()`

React hook that provides translation functionality.

#### Returns

- `t(key, params?)`: Translation function
  - `key`: Translation key (with full TypeScript autocomplete)
  - `params`: Optional object for parameter interpolation
- `language`: Current active language
- `setLanguage(lang)`: Function to change the current language
- `supportedLanguages`: Array of supported languages

## Advanced Usage

### Nested Translations

Organize your translations in a hierarchical structure:

**translations/en.json**

```json
{
  "auth": {
    "login": {
      "title": "Sign In",
      "button": "Login",
      "forgot": "Forgot password?"
    }
  },
  "nav": {
    "home": "Home",
    "about": "About"
  }
}
```

**translations/tr.json**

```json
{
  "auth": {
    "login": {
      "title": "Giriş Yap",
      "button": "Giriş",
      "forgot": "Şifremi unuttum?"
    }
  },
  "nav": {
    "home": "Ana Sayfa",
    "about": "Hakkında"
  }
}
```

```typescript
import { createInstance } from '@ravshansbox/react-i18n'
import en from './translations/en.json'
import tr from './translations/tr.json'

const { useTranslation } = createInstance({
  supportedLanguages: ['en', 'tr'],
  defaultLanguage: 'en',
  translations: { en, tr },
})

// Use with dot notation
t('auth.login.title') // "Sign In"
t('nav.home') // "Home"
```

### Parameter Interpolation

Insert dynamic values into your translations:

**translations/en.json**

```json
{
  "greeting": "Hello, {{name}}!",
  "notification": "You have {{count}} new messages",
  "complex": "Welcome {{user}}! Today is {{day}} and you have {{pending}} tasks."
}
```

**translations/tr.json**

```json
{
  "greeting": "Merhaba, {{name}}!",
  "notification": "{{count}} yeni mesajınız var",
  "complex": "Hoşgeldiniz {{user}}! Bugün {{day}} ve {{pending}} göreviniz var."
}
```

```typescript
import { createInstance } from '@ravshansbox/react-i18n'
import en from './translations/en.json'
import tr from './translations/tr.json'

const { useTranslation } = createInstance({
  supportedLanguages: ['en', 'tr'],
  defaultLanguage: 'en',
  translations: { en, tr },
})

// Usage
t('greeting', { name: 'Alice' }) // "Hello, Alice!"
t('notification', { count: 5 }) // "You have 5 new messages"
t('complex', {
  user: 'John',
  day: 'Monday',
  pending: 3,
}) // "Welcome John! Today is Monday and you have 3 tasks."
```

### Type Safety

The library provides full TypeScript support:

```typescript
// ✅ Valid - key exists and is a string
t('greeting')

// ✅ Valid - nested key exists
t('messages.success')

// ❌ TypeScript error - key doesn't exist
t('nonexistent')

// ❌ TypeScript error - trying to access object, not string
t('messages')

// ✅ Valid - parameter interpolation
t('welcome', { name: 'User' })

// ✅ TypeScript will enforce parameter types
t('greeting', { name: 123 }) // Works - converts to string
```

## Requirements

- React 18.0.0 or higher
- TypeScript (recommended for full type safety)

## License

MIT License - see the [LICENSE](LICENSE) file for details.