npm package: @kopynator/angular
Description: Angular wrapper for the Kopynator i18n platform. Works with Angular 17+ (Signals support).
Latest version: 2.0.0

# @kopynator/angular

Angular wrapper for the Kopynator i18n platform. Works with Angular 17+ (Signals support).

## Features
- **Signal-based**: Reacts to locale changes and loading states using Angular Signals.
- **Pipe & Directive**: Use `{{ 'key' | kopy }}` or `<span [kopy]="'key'"></span>`.
- **Impure Pipe**: Automatically updates when translations are loaded or changed.

## Installation
```bash
npm install @kopynator/core @kopynator/angular
```

## Usage

### 1. Configuration
In your `app.config.ts`:

```typescript
import { provideKopynator } from '@kopynator/angular';

export const appConfig: ApplicationConfig = {
  providers: [
    provideKopynator({
      apiKey: 'YOUR_API_KEY', // Get it from https://www.kopynator.com
      defaultLocale: 'en',
      mode: 'live',
      languages: ['es', 'en']
    })
  ]
};
```

#### Configuration Options

| Option | Type | Description |
|---|---|---|
| `apiKey` | `string` | **Required**. Your public project token found at [kopynator.com](https://www.kopynator.com). |
| `defaultLocale` | `string` | **Required**. The fallback language if no other is detected (e.g. 'en'). |
| `languages` | `string[]` | **Required for 'local' mode**. Array of supported language codes. |
| `mode` | `'local' \| 'hybrid' \| 'live'` | Determines how translations are loaded. See below. |

#### Loading Modes

1.  **`local`**:
    *   **Offline First**. Only loads JSON files from your `assets/i18n` folder.
    *   Does **not** make any network requests to Kopynator API.
    *   Ideal for development without internet or strict offline requirements.

2.  **`live`**:
    *   **Cloud First**. Fetches the latest translations directly from the Kopynator CDN/API.
    *   Ensures users always see the most up-to-date content without deploying a new version of your app.
    *   Requires internet connection.

3.  **`hybrid`** (Recommended):
    *   **Best of Both Worlds**. First loads your local JSON files (instant render), then fetches updates from the Cloud in the background.
    *   Merges both sources, giving priority to the Cloud for any new or updated keys.

### 2. Uso en plantillas (como ngx-translate)

Igual que **ngx-translate**: solo configuras el provider y usas el pipe o la directiva. **No hace falta ningún wrapper** (ni `<kopy-ready>` ni lógica extra en el componente raíz).

- **`provideKopynator`** usa `APP_INITIALIZER`: las traducciones se cargan **antes** de que arranque la app, así que la primera vista ya tiene las traducciones listas.
- El **pipe** y la **directiva** devuelven cadena vacía mientras no estén listas (nunca muestran la clave en crudo).

Tu `app.html` puede ser solo:

```html
<router-outlet></router-outlet>
```

O con header/selector:

```html
<header><kopy-selector></kopy-selector></header>
<main><router-outlet></router-outlet></main>
```

### 3. In Templates
```html
<!-- Using Pipe -->
<h1>{{ 'welcome_title' | kopy }}</h1>

<!-- Using Directive -->
<p [kopy]="'description'" [kopyParams]="{ name: 'Carlos' }"></p>

<!-- Language selector -->
<kopy-selector></kopy-selector>

<!-- Using Service -->
<button (click)="kopyService.setLocale('es')">Español</button>
```

### SSR: idioma guardado sin parpadeo

Al cambiar de idioma se guarda en `localStorage` y en la cookie `kopy_locale`. Para que el **servidor** pinte ya con ese idioma (y no se vea español → idioma guardado), proporciona `KOPY_INITIAL_LOCALE` desde la request en `app.config.server.ts`:

```ts
import { inject, REQUEST } from '@angular/core';
import { KOPY_INITIAL_LOCALE, getKopyLocaleFromCookieHeader } from '@kopynator/angular';

// en providers del server:
{
  provide: KOPY_INITIAL_LOCALE,
  useFactory: () => {
    const req = inject(REQUEST, { optional: true }) as { headers?: { cookie?: string } } | null;
    return req?.headers?.cookie ? getKopyLocaleFromCookieHeader(req.headers.cookie) : null;
  }
}
```

### (Opcional) Componente \<kopy-ready\>

Solo si necesitas ocultar un bloque concreto hasta que estén listas las traducciones, puedes usar `<kopy-ready>`. En la mayoría de proyectos **no es necesario**; el `APP_INITIALIZER` carga las traducciones antes del bootstrap (igual que ngx-translate), con o sin SSR.

```html
<kopy-ready>
  <router-outlet></router-outlet>
</kopy-ready>
```