Skip to main content

🌍 Internationalization (i18n) plugin

The Internationalization (i18n) feature allows Strapi users to create, manage and distribute localized content in different languages, called "locales". For more information about the concept of internationalization, please refer to the W3C definition.

The i18n feature:

  • allows admin panel users to create several localized versions of their content (see User Guide)
  • allows developers to build localized projects by fetching and consuming the right content depending on the country/language of the audience.
✏️ Note

The i18n feature does not automatically translate the users' content nor adapt the admin interface to languages specificities (e.g., displaying the admin panel in Right To Left format).

Installation​

β˜‘οΈ Prerequisites

The Internationalization (i18n) feature is installed by default on all Strapi applications running on version 3.6.0 or higher. For lower versions, a migration is needed (see Update Strapi version), as well as a manual installation of the plugin.

The feature can be installed:

yarn strapi install i18n

Configuration of the default locale​

A STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE environment variable can be configured to set the default locale for your environment. The value used for this variable should be an ISO country code (see full list of available locales).

This is useful when a Strapi application is deployed in production, with the i18n feature installed and enabled for your content types the first time. On a fresh i18n installation, en is set as default locale. If the database does not contain any locale, and no STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE is set for the environment, all documents of content types that have localization enabled will be automatically migrated to the en locale.

Use locale with the REST API​

The Internationalization (i18n) feature adds new abilities to the REST API.

β˜‘οΈ Prerequisites

To work with API content for a locale, please ensure the locale has been already added to Strapi in the admin panel.

The locale API parameter can be used to work documents only for a specified locale. locale takes a locale code as a value (see full list of available locales).

πŸ’‘ Tip

If the locale parameter is not defined, it will be set to the default locale. en is the default locale when a new Strapi project is created, but another locale can be set as the default locale in the admin panel.

For instance, by default, a GET request to /api/restaurants will return the same response as a request to /api/restaurants?locale=en.

The following table lists the new possible use cases added by i18n to the REST API and gives syntax examples (you can click on requests to jump to the corresponding section with more details):

Use caseSyntax example
and link for more information
Get all documents in a specific localeGET /api/restaurants?locale=fr
Get a specific locale version for a documentGET /api/restaurants/abcdefghijklmno456?locale=fr
Create a new document for the default localePOST /api/restaurants
+ pass attributes in the request body
Create a new document for a specific localePOST /api/restaurants
+ pass attributes and locale in the request body
Create a new, or update an existing, locale version for an existing documentPUT /api/restaurants/abcdefghijklmno456?locale=fr
+ pass attributes in the request body
Delete a specific locale version of a documentDELETE /api/restaurants/abcdefghijklmno456?locale=fr
πŸ— GraphQL API not ready yet

The GraphQL API is currently being reworked and its API documentation will be added soon.

Get all documents in a specific locale​

Example request

GET http://localhost:1337/api/restaurants?locale=fr

Example response
{
"data": [
{
"id": 5,
"documentId": "h90lgohlzfpjf3bvan72mzll",
"Title": "Meilleures pizzas",
"Body": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"text": "On dΓ©guste les meilleures pizzas de la ville Γ  la Pizzeria Arrivederci."
}
]
}
],
"createdAt": "2024-03-06T22:08:59.643Z",
"updatedAt": "2024-03-06T22:10:21.127Z",
"publishedAt": "2024-03-06T22:10:21.130Z",
"locale": "fr"
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}

Get a document in a specific locale​

To get a specific document in a given locale, add the locale parameter to the query:

Use caseSyntax format and link for more information
In a collection typeGET /api/content-type-plural-name/document-id?locale=locale-code
In a single typeGET /api/content-type-singular-name?locale=locale-code

Collection types​

To get a specific document in a collection type in a given locale, add the locale parameter to the query, after the documentId:

Example request

GET /api/restaurants/lr5wju2og49bf820kj9kz8c3?locale=fr

Example response
{
"data": [
{
"id": 22,
"documentId": "lr5wju2og49bf820kj9kz8c3",
"Name": "Biscotte Restaurant",
"Description": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"text": "Bienvenue au restaurant Biscotte! Le Restaurant Biscotte propose une cuisine Γ  base de produits frais et de qualitΓ©, souvent locaux, biologiques lorsque cela est possible, et toujours produits par des producteurs passionnΓ©s."
}
]
}
],
// …
"locale": "fr"
},
// …
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 3
}
}
}

Single types​

To get a specific single type document in a given locale, add the locale parameter to the query, after the single type name:

Example request

GET /api/homepage?locale=fr

Example response
{
"data": {
"id": 10,
"documentId": "ukbpbnu8kbutpn98rsanyi50",
"Title": "Page d'accueil",
"Body": null,
"createdAt": "2024-03-07T13:28:26.349Z",
"updatedAt": "2024-03-07T13:28:26.349Z",
"publishedAt": "2024-03-07T13:28:26.353Z",
"locale": "fr"
},
"meta": {}
}

Create a new localized document for a collection type​

To create a localized document from scratch, send a POST request to the Content API. Depending on whether you want to create it for the default locale or for another locale, you might need to pass the locale parameter in the request's body

Use caseSyntax format and link for more information
Create for the default localePOST /api/content-type-plural-name
Create for a specific localePOST /api/content-type-plural-name
+ pass locale in request body

For the default locale​

If no locale has been passed in the request body, the document is created using the default locale for the application:

Example request

POST http://localhost:1337/api/restaurants

{
"data": {
"Name": "Oplato",
}
}
Example response
{
"data": {
"id": 13,
"documentId": "jae8klabhuucbkgfe2xxc5dj",
"Name": "Oplato",
"Description": null,
"createdAt": "2024-03-06T22:19:54.646Z",
"updatedAt": "2024-03-06T22:19:54.646Z",
"publishedAt": "2024-03-06T22:19:54.649Z",
"locale": "en"
},
"meta": {}
}

For a specific locale​

To create a localized entry for a locale different from the default one, add the locale attribute to the body of the POST request:

Example request

POST http://localhost:1337/api/restaurants

{
"data": {
"Name": "She's Cake",
"locale": "fr"
}
}
Example response
{
"data": {
"id": 15,
"documentId": "ldcmn698iams5nuaehj69j5o",
"Name": "She's Cake",
"Description": null,
"createdAt": "2024-03-06T22:21:18.373Z",
"updatedAt": "2024-03-06T22:21:18.373Z",
"publishedAt": "2024-03-06T22:21:18.378Z",
"locale": "en"
},
"meta": {}
}

Create a new, or update an existing, locale version for an existing document​

With PUT requests sent to an existing document, you can:

  • create another locale version of the document,
  • or update an existing locale version of the document.

Send the PUT request to the appropriate URL, adding the locale=your-locale-code parameter to the query URL and passing attributes in a data object in the request's body:

Use caseSyntax format and link for more information
In a collection typePUT /api/content-type-plural-name/document-id?locale=locale-code
In a single typePUT /api/content-type-singular-name?locale=locale-code
βœ‹ Caution

When creating a localization for existing localized entries, the body of the request can only accept localized fields.

πŸ’‘ Tip

The Content-Type should have the createLocalization permission enabled, otherwise the request will return a 403: Forbidden status.

✏️ Note

It is not possible to change the locale of an existing localized entry. When updating a localized entry, if you set a locale attribute in the request body it will be ignored.

In a collection type​

To create a new locale for an existing document in a collection type, add the locale parameter to the query, after the documentId, and pass data to the request's body:

Example request: Creating a French locale for an existing restaurant

PUT http://localhost:1337/api/restaurants/lr5wju2og49bf820kj9kz8c3?locale=fr

{
data: {
"Name": "She's Cake in French",
}
}
Example response
{
"data": {
"id": 19,
"documentId": "lr5wju2og49bf820kj9kz8c3",
"Name": "She's Cake in French",
"Description": null,
"createdAt": "2024-03-07T12:13:09.551Z",
"updatedAt": "2024-03-07T12:13:09.551Z",
"publishedAt": "2024-03-07T12:13:09.554Z",
"locale": "fr"
},
"meta": {}
}

In a single type​

To create a new locale for an existing single type document, add the locale parameter to the query, after the single type name, and pass data to the request's body:

Example: Create a FR locale for an existing Homepage single type

PUT http://localhost:1337/api/homepage?locale=fr

{
"data": {
"Title": "Page d'accueil"
}
}
Example response
{
"data": {
"id": 10,
"documentId": "ukbpbnu8kbutpn98rsanyi50",
"Title": "Page d'accueil",
"Body": null,
"createdAt": "2024-03-07T13:28:26.349Z",
"updatedAt": "2024-03-07T13:28:26.349Z",
"publishedAt": "2024-03-07T13:28:26.353Z",
"locale": "fr"
},
"meta": {}
}

Delete a locale version of a document​

To delete a locale version of a document, send a DELETE request with the appropriate locale parameter.

DELETE requests only send a 204 HTTP status code on success and do not return any data in the response body.

In a collection type​

To delete only a specific locale version of a document in a collection type, add the locale parameter to the query after the documentId:

Example request

DELETE /api/restaurants/abcdefghijklmno456?locale=fr

In a single type​

To delete only a specific locale version of a single type document, add the locale parameter to the query after the single type name:

Example request

DELETE /api/homepage?locale=fr

Use locale with the GraphQL API​

The i18n feature adds new features to the GraphQL API:

  • The locale field is added to the GraphQL schema.
  • GraphQL can be used:
    • to query documents for a specific locale with the locale argument
    • for mutations to create, update, and delete documents for a specific locale

Fetch all documents in a specific locale​

To fetch all documents for a specific locale, pass the locale argument to the query:

Example request
query {
restaurants(locale: "fr") {
documentId
name
locale
}
}
Example response
{
"data": {
"restaurants": [
{
"documentId": "a1b2c3d4e5d6f7g8h9i0jkl",
"name": "Restaurant Biscotte",
"locale": "fr"
},
{
"documentId": "m9n8o7p6q5r4s3t2u1v0wxyz",
"name": "Pizzeria Arrivederci",
"locale": "fr"
},
]
}
}

Fetch a document in a specific locale​

To fetch a documents for a specific locale, pass the documentId and the locale arguments to the query:

Example query
query Restaurant($documentId: ID!, $locale: I18NLocaleCode) {
restaurant(documentId: "a1b2c3d4e5d6f7g8h9i0jkl", locale: "fr") {
documentId
name
description
locale
}
}
Example response
{
"data": {
"restaurant": {
"documentId": "lviw819d5htwvga8s3kovdij",
"name": "Restaurant Biscotte",
"description": "Bienvenue au restaurant Biscotte!",
"locale": "fr"
}
}
}

Create a new localized document​

The locale field can be passed to create a localized document for a specific locale (for more information about mutations with GraphQL, see the GraphQL API documentation).

Example: Create a new restaurant for the French locale
mutation CreateRestaurant($data: RestaurantInput!, $locale: I18NLocaleCode) {
createRestaurant(
data: {
name: "Brasserie Bonjour",
description: "Description in French goes here"
},
locale: "fr"
) {
documentId
name
description
locale
}

Update a document for a specific locale​

A locale argument can be passed in the mutation to update a document for a given locale (for more information about mutations with GraphQL, see the GraphQL API documentation).

Example: Update the description field of restaurant for the French locale
mutation UpdateRestaurant($documentId: ID!, $data: RestaurantInput!, $locale: I18NLocaleCode) {
updateRestaurant(
documentId: "a1b2c3d4e5d6f7g8h9i0jkl"
data: {
description: "New description in French"
},
locale: "fr"
) {
documentId
name
description
locale
}

Delete a locale for a document​

Pass the locale argument in the mutation to delete a specific localization for a document :

mutation DeleteRestaurant($documentId: ID!, $locale: I18NLocaleCode) {
deleteRestaurant(documentId: "xzmzdo4k0z73t9i68a7yx2kk", locale: "fr") {
documentId
}
}