# Comvi i18n

A small i18n library with one i18n instance, a binding for React, Next.js, Vue, Nuxt, Svelte or Solid, and catalogs that come inline or from the Comvi CDN.

Canonical: https://comvi.io/docs/i18n

Comvi i18n is a small, framework-agnostic library for translating apps: one i18n instance, a
binding for React, Next.js, Vue, Nuxt, Svelte or Solid, and `t()` in your components. Catalogs
are plain JSON, inline in your source or served at runtime from the Comvi CDN so a wording change
ships without a redeploy.
**React**

`src/App.tsx`

```tsx
import { useI18n } from '@comvi/react';

export default function App() {
    const { t } = useI18n();
    return <h1>{t('greeting', { name: 'Alice' })}</h1>;
}
```

**Next.js**

`src/app/[locale]/page.tsx`

```tsx
import { getI18n } from '@comvi/next/server';

export default async function Page({ params }: { params: Promise<{ locale: string }> }) {
    const { locale } = await params;
    const { t } = await getI18n({ locale });
    return <h1>{t('greeting', { name: 'Alice' })}</h1>;
}
```

**Vue**

`src/App.vue`

```vue
<script setup lang="ts">
import { useI18n } from '@comvi/vue';
const { t } = useI18n();
</script>

<template><h1>{{ t('greeting', { name: 'Alice' }) }}</h1></template>
```

**Nuxt**

    `app/pages/index.vue`

    ```vue
<script setup lang="ts">
const { t } = useI18n();
</script>

<template><h1>{{ t('greeting', { name: 'Alice' }) }}</h1></template>
```

**Svelte**

`src/routes/+page.svelte`

```svelte
<script lang="ts">
    import { useI18n } from '@comvi/svelte';
    const { t } = useI18n();
</script>

<h1>{$t('greeting', { name: 'Alice' })}</h1>
```

**Solid**

`src/App.tsx`

```tsx
import { useI18n } from '@comvi/solid';

export default function App() {
    const { t } = useI18n();
    return <h1>{t('greeting', { name: 'Alice' })}</h1>;
}
```

**Vanilla**

`src/i18n.ts`

```ts
import { createI18n } from '@comvi/core';

const i18n = createI18n({ locale: 'en', messages: { en: { greeting: 'Hello, {name}!' } } });
await i18n.init();
i18n.t('greeting', { name: 'Alice' }); // "Hello, Alice!"
```

`createI18n()` returns the **i18n instance**: the catalogs, the current locale and `t()`. A
**binding** hands it to components, so `useI18n()` in React, Vue, Svelte or Solid and `getI18n()`
in a Next.js Server Component read the same instance. A loader and the locale detector are
**installers**: you compose them with `.use()`, and what you do not compose is not in your
bundle. The ICU compiler is the constructor option `compiler: icuCompiler`, opted into the same
way.

<Mermaid
code={`flowchart LR
    App["Your components"]
    Binding["Binding<br/>useI18n() / getI18n()"]
    Instance["i18n instance<br/>createI18n()"]
    Inline["Inline catalog<br/>messages: { en: … }"]
    Loader["Loader<br/>.use(cdnLoader({ cdnUrl }))"]
    CDN["Comvi CDN"]

    App --> Binding --> Instance
    Inline --> Instance
    Loader --> Instance
    CDN --> Loader
`}
caption="Components talk to the binding, the binding to the i18n instance. The instance reads its catalog from your source or from a loader; the component does not know which."
/>

## What you get

- [Translate text with t()](/docs/i18n/translation-function): dot-path keys, namespaces, call options and a defined answer for a missing key.
- [Insert values and markup](/docs/i18n/tag-interpolation): `{param}` placeholders, and `<link>` tags a translator can move while your code decides what they render.
- [Pluralize with ICU](/docs/i18n/pluralization): `plural`, `select` and `selectordinal`, one constructor option, correct forms for Ukrainian and Arabic as well as English.
- [Format numbers, dates and currency](/docs/i18n/formatting): `Intl` wrappers bound to the current locale, plus text direction.
- [Switch the locale](/docs/i18n/language-switching): one call, every component that reads the instance re-renders, nothing flashes untranslated.
- [Load translations on demand](/docs/i18n/loading-translations): one chunk per locale, a custom loader, or the Comvi CDN with a bundled fallback.
- [Split translations into namespaces](/docs/i18n/namespaces): load a screen's keys only on that screen.
- [Type-check translation keys](/docs/i18n/type-safety): a misspelled key or a missing parameter is a compile error, from local JSON or from your Comvi project.
- [Render on the server](/docs/i18n/ssr): Next.js, Nuxt, SvelteKit and SolidStart with no hydration mismatch.
- [Handle missing keys and errors](/docs/i18n/error-handling): `t()` never throws in the default configuration; every failure reaches a hook you can wire to your tracker.

Each item has a snippet on [Features](/docs/i18n/features).

## Start here

- [Quick start](/docs/i18n/quick-start): a translated heading and a locale switch in your framework, five minutes, no account.
- [Important defaults](/docs/i18n/important-defaults): the behaviours that surprise people, and why each is the default.

## The platform

The [Comvi platform](/docs/platform) stores the keys, machine-translates new ones and publishes
each locale as JSON on a CDN; `@comvi/plugin-fetch-loader` reads it at runtime and the
[CLI](/docs/cli) generates types for `t()`. None of it is required: the instance works with an
inline catalog, and [Connect to Comvi](/docs/i18n/connect-comvi) is a separate, optional step.

## Read next

- [Limitations](/docs/i18n/limitations): what the library does not do, with what happens instead.
- [Glossary](/docs/i18n/glossary): i18n instance, binding, catalog, installer, and the other words these pages use.
