---
url: /strapi-typed-client/reference/i18n.md
---
# Locales (i18n)

Strapi ships the i18n plugin in the box. Its content API exposes the list of configured locales, and the client wraps it as `client.i18n` — typed, and going through the same auth pipeline, baseURL, error handling, and Next.js cache integration as the rest of the client.

Before this existed you had to reach for `@strapi/client` (or a hand-written `fetch`) just to fill a language switcher.

## Methods

| Method      | Endpoint                | Returns        |
| ----------- | ----------------------- | -------------- |
| `locales()` | `GET /api/i18n/locales` | `I18nLocale[]` |

## `I18nLocale`

```ts
interface I18nLocale {
    id: number
    documentId: string
    name: string
    code: string
    isDefault: boolean
    createdAt: string
    updatedAt: string
    publishedAt: string | null
}
```

## Listing locales

```ts
const locales = await client.i18n.locales()

const codes = locales.map(locale => locale.code)
// ['en', 'de', 'fr']

const fallback = locales.find(locale => locale.isDefault)?.code ?? 'en'
```

A language switcher, with the display names Strapi already stores:

```ts
const options = (await client.i18n.locales()).map(locale => ({
    value: locale.code,
    label: locale.name,
}))
```

Pass a `code` straight to a collection query:

```ts
const articles = await client.articles.find({ locale: 'de' })
```

To write a localization, pass the code as a [write param](/reference/api#write-params). Strapi ignores a `locale` in the request body and writes the default locale instead:

```ts
await client.articles.update(documentId, { title: 'Hallo' }, { locale: 'de' })
```

::: warning Response shape
This route answers with a bare array — there is no `{ data, meta }` envelope, so `locales()` resolves to `I18nLocale[]` directly.
:::

::: warning The route ignores query parameters
`listLocales` reads nothing off the query string: `fields`, `filters`, `sort` and pagination are all silently ignored, and you always get every locale in full. Narrow the result in your own code instead.
:::

::: warning Permissions
The endpoint is not public by default — an anonymous request gets `403 Forbidden`. Either grant the role the `i18n` → `locale` → `find` permission under **Settings → Users & Permissions → Roles**, or call it with an API token.
:::

::: tip Locale codes are not always two letters
Strapi accepts regional codes such as `en-US` and `pt-BR`, so treat `code` as an opaque string rather than assuming a two-letter shape.
:::
