---
title: "Localization: Change languages in JavaScript PDF viewer | Nutrient"
canonical_url: "https://www.nutrient.io/guides/web/features/localization/"
md_url: "https://www.nutrient.io/guides/web/features/localization.md"
last_updated: "2026-05-18T04:02:30.361Z"
description: "Localization: Change languages in JavaScript PDF viewer | guide for Nutrient Web SDK with detailed instructions and code examples."
---

# Localization: Updating languages in our JavaScript PDF viewer

Nutrient Web SDK comes with many built-in languages:

- Chinese Simplified / Chinese Traditional (zh-Hans/zh-Hant)

- Croatian (hr)

- Czech (cs)

- Danish (da)

- Dutch (nl)

- English (en)

- English United Kingdom (en-GB)

- Finnish (fi)

- French (fr)

- French Canada (fr-CA)

- German (de)

- Greek (el)

- Indonesian (id)

- Italian (it)

- Japanese (ja)

- Korean (ko)

- Malay (ms)

- Norwegian Bokmål (nb-NO)

- Polish (pl)

- Portuguese Brazil / Portugal (pt/pt-PT)

- Russian (ru)

- Slovak (sk)

- Slovenian (sl)

- Spanish (es)

- Swedish (sv)

- Thai (th)

- Turkish (tr)

- Ukrainian (uk)

- Welsh (cy)

## Adding Additional Localization to Nutrient

Nutrient Web SDK allows the addition of new locales in a simple and straightforward manner.

`NutrientViewer.I18n` consists of two parts, which the localization engine uses when translating:

- [`NutrientViewer.I18n.locales`](https://www.nutrient.io/api/web/NutrientViewer.I18n.html) — an array of supported locales.

- [`NutrientViewer.I18n.messages`](https://www.nutrient.io/api/web/NutrientViewer.I18n.html) — an object containing `{ locale: translatedMessagesObject }` pairs, e.g. `{ en: {} }`.

Since Nutrient Web SDK 2020.1, pluralization and formatting rules don’t need to be added, as the native [Intl API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) is used instead (a change introduced in [`react-intl`](https://github.com/formatjs/react-intl) v3).

Browsers that don’t support the [Intl API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) (like Safari 13 and below) will include a polyfill for `Intl.PluralRules`, as well as an individual polyfill for each of the supported locales. If you want to keep supporting these browsers when providing additional locales, you can do so by including the corresponding locale polyfill:

```js

// Add the locale to the locales list (Wolof language).
NutrientViewer.I18n.locales.push("wo");
// Is this browser using the `Intl.PluralRules` polyfill?
if (Intl.PluralRules.polyfilled) {
  // Then include the plural rules locale data polyfill.
  await import("@formatjs/intl-pluralrules/dist/locale-data/wo");
}
// Add Wolof translations for messages.
NutrientViewer.I18n.messages["wo"] = wolofMessages;
// Change current language to Wolof.
instance.setLocale("wo");

```

Add the locale data polyfills to your local `node_modules` folder by installing them using `npm`:

```npm

npm i @formatjs/intl-pluralrules

```

As a result of these changes, `NutrientViewer.I18n.localizationData`, which was used before Nutrient Web SDK 2020.1 to add localization data, is now deprecated.

Let’s say we want to add support for French (note this is just an example and Nutrient Web SDK already supports French). To do this, we have to add the information about `test` to the two objects above, as shown below.

1. Push the new locale to the `NutrientViewer.I18n.locales` array:

   ```js

   NutrientViewer.I18n.locales.push("fr");
   ```

2. Add the translated messages to the `NutrientViewer.I18n.messages` object:

   ```js

   NutrientViewer.I18n.messages.fr = {
     searchNextMatch: "Prochain",
     // Other translations here.
   };
   ```

   You can use the English messages object (`NutrientViewer.I18n.messages.en`) as a template.

3. Optionally, add the polyfill for browsers not supporting the Intl API:

   ```js

   // Is this browser using the `Intl.PluralRules` polyfill?
   if (Intl.PluralRules.polyfilled) {
     // Then include the plural rules locale data polyfill.
     await import("@formatjs/intl-pluralrules/dist/locale-data/fr");
   }
   ```

To add locale data for a new language:

- Follow the download instructions on [the `react-intl` page](https://formatjs.io/docs/polyfills/intl-pluralrules/).

- Load `react-intl/locale-data/YourNewLocaleSymbol` (the locale data) either via the `script` tag or `import`.

- Optionally, add the localization data polyfill for browsers not supporting the `Intl` API.

Now your application is ready to be used in French.

Note that we don’t store your information. As such, you need to persist translations in your data store of choice.

## Customizing existing translations

Once localization data is loaded, all the translated messages will be available on the [`NutrientViewer.I18n.messages`](https://www.nutrient.io/api/web/NutrientViewer.I18n.html) object.

### Simple customization

To customize a string for a specific locale, you can mutate this object directly:

```js

console.log(NutrientViewer.I18n.messages.en.searchNextMatch);
// > "Next"

NutrientViewer.I18n.messages.en.searchNextMatch =
  "Go to the next search result.";
console.log(NutrientViewer.I18n.messages.en.searchNextMatch);
// > "Go to the next search result."

```

### Overriding multiple translations

By default, translations are only available after you create an instance of Nutrient Web SDK. To modify translations before creating an instance, use the [`NutrientViewer.I18n.preloadLocalizationData`](https://www.nutrient.io/api/web/NutrientViewer.I18n.html) method:

```js

await NutrientViewer.I18n.preloadLocalizationData("en");
NutrientViewer.I18n.messages.en.searchNextMatch =
  "Go to the next search result.";
//...
NutrientViewer.load({
  locale: "en",
  // Other configuration options.
});

```

To override multiple translations at once, use the spread operator to merge your custom text with existing translations:

```js

NutrientViewer.I18n.preloadLocalizationData("en").then(() => {
  NutrientViewer.I18n.messages.en = {...NutrientViewer.I18n.messages.en,
    loading: "Custom loading text",
    annotations: "Custom annotations label",
    searchNextMatch: "Go to the next result",
    // Add more custom translations here.
  };
});

NutrientViewer.load({
  locale: "en",
  // Other configuration options.
}).then((instance) => {
  console.log("Nutrient loaded with custom translations!");
});

```

If [`NutrientViewer.I18n.preloadLocalizationData`](https://www.nutrient.io/api/web/NutrientViewer.I18n.html) throws an error like `PSPDFKitError: I18n: Cannot find translations for "en"`, pass the `baseUrl` option as the second parameter:

```js

NutrientViewer.I18n.preloadLocalizationData("en", {
  baseUrl: "path/to/your/assets",
});

```

This ensures the localization files are loaded from the correct location.

## Forcing a specific language

By default, Nutrient Web SDK tries to detect the language using the `navigator.language` value. However, the `locale` can be programmatically set before loading Nutrient via the [locale configuration option](https://www.nutrient.io/api/web/NutrientViewer.Configuration.html#locale):

```js

NutrientViewer.load({
  locale: "de",
  // Other configuration options.
});

```

The locale can be changed at runtime using the [`Instance#setLocale`](https://www.nutrient.io/api/web/NutrientViewer.Instance.html#setLocale) instance method:

```js

await instance.setLocale("de");
console.log("Successfully changed the language to German.");

```
---

## Related pages

- [Create a custom toolbar in our JavaScript PDF viewer](/guides/web/user-interface/create-a-toolbar.md)
- [PDF form field date and time picker](/guides/web/user-interface/date-and-time-picker.md)
- [User interface customization in our JavaScript PDF viewer](/guides/web/user-interface.md)
- [Form Designer: Create and edit PDF form fields using JavaScript](/guides/web/user-interface/form-designer.md)
- [Create and customize redactions in our PDF viewer](/guides/web/user-interface/redaction.md)
- [Right-to-left](/guides/web/user-interface/rtl-languages.md)
- [Custom overlays in our viewer](/guides/web/customizing-the-interface/creating-custom-overlay-items.md)
- [Customizing the search UI in our PDF viewer toolbar](/guides/web/user-interface/search.md)
- [User interface troubleshooting](/guides/web/user-interface/troubleshooting.md)
- [View state in our JavaScript PDF viewer](/guides/web/customizing-the-interface/viewstate.md)

