---
title: "1.21 release notes"
canonical_url: "https://www.nutrient.io/guides/web/release-notes/1-21/"
md_url: "https://www.nutrient.io/guides/web/release-notes/1-21.md"
last_updated: "2026-08-19T00:00:00.000Z"
description: "Lists important changes for Nutrient Web SDK 1.21"
---

Nutrient Web SDK 1.21 finishes the localization of the viewer: Every UI string now renders translated in all 32 locales, the component library’s strings became overridable, and right-to-left layout is applied for regional Arabic and Hebrew locales. It also records who created an annotation or comment, adds print-production rendering controls for overprinting and 100 percent K black, surfaces terminal page render failures through a new `page.renderError` event, and extends template population to XLSX and PPTX. See the [changelog](https://www.nutrient.io/guides/web/changelog.md#1.21.0) for full details.

### Renamed message placeholders

Five messages had their named placeholders renamed to the positional `{arg0}` form. **If you override any of these keys through `NutrientViewer.I18n.messages`, update your translation to use the new placeholder — a translation that still uses the old name renders the placeholder as literal text.**

| Message ID                  | Old placeholder   | New placeholder |
| --------------------------- | ----------------- | --------------- |
| `formDesignerPopoverTitle`  | `{formFieldType}` | `{arg0}`        |
| `styleSectionLabel`         | `{formFieldType}` | `{arg0}`        |
| `formFieldNameExists`       | `{formFieldName}` | `{arg0}`        |
| `searchDocumentDescription` | `{min}`           | `{arg0}`        |
| `shapePointAdded`           | `{count}`         | `{arg0}`        |

```js

NutrientViewer.load({
  // Before: named placeholder.
  // I18n: { messages: { en: { searchDocumentDescription: "Type at least {min} characters" } } }

  // After: positional placeholder.
  I18n: {
    messages: {
      en: { searchDocumentDescription: "Type at least {arg0} characters" },
    },
  },
});

```

Only these five keys changed. Every other overridden message keeps its placeholders.

### Complete UI localization

Parts of the interface — the comment editor toolbar among them — previously rendered in English in every non-English locale. Those strings are now translated across all 32 locales, along with the annotation blend mode labels in Thai and the Screen blend mode in Arabic. The English wording of several strings was corrected in the process, so a few labels changed: For example, the custom color dialog is now titled “New Color.”

The component library’s strings are now part of the SDK’s message catalog, which means they carry message IDs and can be customized through `NutrientViewer.I18n.messages` like any other string. For the full list of IDs, their English text, and the surface each one appears on, refer to the [localization](https://www.nutrient.io/api/web/documents/Localization.html) guide in the API reference.

A translation that can’t be formatted — because of invalid ICU MessageFormat syntax, for example — is ignored and the English text is used, as before. It now also logs a console warning naming the message key, the locale, and the formatter error, so a broken override is visible instead of silently falling back.

### Right-to-left layout for regional locales

The UI now switches to a right-to-left layout whenever the active language is Arabic or Hebrew, not only for the exact `ar` and `he` tags. This covers three cases that previously stayed left-to-right: a regional locale such as `ar-EG`, a browser language of Arabic or Hebrew when no `locale` is configured, and a locale changed after load with `setLocale()`.

### Annotation and comment attribution

`Annotation.createdBy` and `Comment.createdBy` expose the user ID of the authenticated user that created the record:

```js

const annotations = await instance.getAnnotations(0);
annotations.forEach((annotation) => {
  console.log(annotation.createdBy);
});

```

Both properties are read-only and assigned by the backend — a locally set value is never sent. They’re available on server-backed deployments only, and are `null` for records created without an authenticated user, or when the server holds an author it can no longer resolve to an upstream user ID. `Annotation.createdBy` requires Instant synchronization against Document Engine 1.18.0 or later.

### Print-production rendering

Two configuration options control rendering fidelity for prepress and soft-proofing workflows. Documents that don’t use CMYK color or overprinting are unaffected by either option.

```js

NutrientViewer.load({
  overprintPreview: NutrientViewer.OverprintPreview.OFF,
  blackRendering: NutrientViewer.BlackRendering.PURE_BLACK,
  //...
});

```

- `overprintPreview` controls whether the renderer simulates the overprinting a document uses, where overlapping inks print on top of each other instead of knocking each other out. It defaults to `AUTO`, which simulates overprinting when the document uses it; `OFF` disables the simulation.

- `blackRendering` controls how exact 100 percent K-only CMYK black is rendered. It defaults to `ACCURATE`, which renders it as the dark charcoal Acrobat shows on screen; `PURE_BLACK` maps it to `#000000` instead, which some print workflows prefer for checking black-only content.

In server-backed mode, both options require Document Engine 1.18.0 or later and are ignored by older servers.

### Terminal page render failures

A page render that exhausts WebAssembly memory is retried once. When the retry also fails, the SDK now displays a localized page-level error and emits `page.renderError`, so your application can react instead of leaving the user with a blank page:

```js

instance.addEventListener("page.renderError", (event) => {
  if (event.error instanceof NutrientViewer.OutOfMemoryError) {
    console.log(event.pageIndex, event.pageStillDisplaysContent);
  }
});

```

`pageStillDisplaysContent` reports whether the page is still showing earlier, lower-resolution content when the event is emitted. The device itself can still have free memory — the failure is specific to the WebAssembly heap.

### XLSX and PPTX template population

`populateDocumentTemplate()` now accepts XLSX and PPTX templates in addition to DOCX, and it returns the populated file as an `ArrayBuffer`.

XLSX templates process every worksheet and support placeholders, conditions, row loops, images, and typed number, date, percentage, and Boolean cells. Column loops and list expansion within a single cell aren’t supported, and formula references, structured table ranges, and defined names aren’t adjusted when row loops insert rows. PPTX templates support placeholders, loops, conditions, tables, and images on slides; slide masters, slide layouts, and speaker notes aren’t processed.

### Other additions

- The API reference ships a [localization](https://www.nutrient.io/api/web/documents/Localization.html) guide listing the locales the SDK provides catalogs for and every overridable message ID.

- `setLocale()` and `preloadLocalizationData()` throw a clearer error when a locale can’t be loaded and expose the underlying failure as `error.cause`.

- AI Assistant agent skills now require a `description`, which the agent uses to decide when to apply each skill.

- Dark-color fidelity of Multiply and related blend modes in CMYK transparency groups is improved by blending in the group’s color space.

### Rendering

- Fixes non-isolated transparency groups compositing their backdrop twice, which rendered blended content too dark or washed out.

- Fixes missing page content when rendering PDFs with certain inline images.

- Fixes missing CJK text and incorrect Yen symbols in PDFs that use configured font substitutions.

- Fixes the black box of an applied redaction being misplaced and incorrectly sized when the redacted content sits inside a transformed form XObject.

- Fixes layer visibility changes through `setLayersVisibilityState()` or the layers sidebar hiding content in optional content groups that `getLayers()` doesn’t expose, such as page-level OCGs in CAD documents. These groups now keep the document’s native visibility.

- Fixes slow saving of free text annotations containing emojis.

### Forms and document editing

- Fixes text form fields rejecting all input when their JavaScript Keystroke script calls `AFMergeChange` or `AFExtractNums`.

- Fixes editing a radio button option in Form Creator moving the group’s option values onto the wrong widgets when the document was exported.

- Fixes `applyRedactions()` being skipped when batched with page move or removal operations.

- Fixes keyboard page reordering in the Document Editor losing its drop position when the interface updates mid-drag.

### Collaboration

- Fixes a comment edit being silently dropped when it was made in the brief window between the comment’s create request being sent and the server’s acceptance of it.

- Fixes an unsaved comment draft carrying over into another comment thread when switching between threads.

### User interface and accessibility

- Fixes the measurement scale target unit picker announcing the source unit picker’s label to screen readers.

- Fixes Japanese and Korean UI strings that displayed stray characters instead of a value, dropped the unit after a point size, or reversed the two numbers in “N of M” counters such as the search result position.

- Fixes translations in Czech, Slovak, and Dutch that rendered a raw placeholder or failed to render, affecting the comment count, the comment thread label, and the duplicate form field name error.

### Loading, platform, and API reference

- Fixes a Content Security Policy violation reported on every load when using the recommended `script-src 'self' 'wasm-unsafe-eval'` policy.

- Fixes the import of annotation and action JSON whose numeric fields aren’t finite numbers, which previously produced annotations that render incorrectly.

- Fixes the missing `Serializers.BookmarkJSON` properties in the API reference.

For a full list of fixes, refer to the [changelog](https://www.nutrient.io/guides/web/changelog.md#1.21.0).

Document Engine 1.5.6 or later can run this release. In server-backed mode, using `SearchType.WORD_BASED`, removing password protection during PDF export, and removing annotation notes after an XFDF roundtrip require Document Engine 1.16.0 or later. Document-defined annotation tab order, `Annotation.createdBy`, `overprintPreview`, and `blackRendering` require Document Engine 1.18.0 or later. See the [Web SDK and Document Engine compatibility requirements](https://www.nutrient.io/guides/document-engine/viewer/client-integration/web.md#version-compatibility).

For a complete list of changes, bug fixes, and improvements, refer to the [changelog](https://www.nutrient.io/guides/web/changelog.md#1.21.0). For previous release notes, refer to the [Web SDK 1.20 release notes](https://www.nutrient.io/guides/web/release-notes/1-20.md). We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.
---

## Related pages

- [1 0](/guides/web/release-notes/1-0.md)
- [1 1](/guides/web/release-notes/1-1.md)
- [1 10](/guides/web/release-notes/1-10.md)
- [1 11](/guides/web/release-notes/1-11.md)
- [1 12](/guides/web/release-notes/1-12.md)
- [1 13 1](/guides/web/release-notes/1-13-1.md)
- [1 13](/guides/web/release-notes/1-13.md)
- [1 14](/guides/web/release-notes/1-14.md)
- [1 15](/guides/web/release-notes/1-15.md)
- [1 16](/guides/web/release-notes/1-16.md)
- [1 17](/guides/web/release-notes/1-17.md)
- [1 18](/guides/web/release-notes/1-18.md)
- [1 19](/guides/web/release-notes/1-19.md)
- [1 2](/guides/web/release-notes/1-2.md)
- [1 20](/guides/web/release-notes/1-20.md)
- [1 3](/guides/web/release-notes/1-3.md)
- [1 4](/guides/web/release-notes/1-4.md)
- [1 5](/guides/web/release-notes/1-5.md)
- [1 6](/guides/web/release-notes/1-6.md)
- [1 7](/guides/web/release-notes/1-7.md)
- [1 8](/guides/web/release-notes/1-8.md)
- [1 9](/guides/web/release-notes/1-9.md)
- [2017 3](/guides/web/release-notes/2017-3.md)
- [2017 6](/guides/web/release-notes/2017-6.md)
- [Update your PSPDFKit for Web to version 2017.7](/guides/web/release-notes/2017-7.md)
- [Upgrade annotations in PSPDFKit Web 2017.8](/guides/web/release-notes/2017-8.md)
- [Explore new features in PSPDFKit for Web 2017.9](/guides/web/release-notes/2017-9.md)
- [New features in the 2018.1 migration guide](/guides/web/release-notes/2018-1.md)
- [PSPDFKit for Web 2018.2 migration insights](/guides/web/release-notes/2018-2.md)
- [Discover the new features in PSPDFKit for Web 2018.3](/guides/web/release-notes/2018-3.md)
- [Explore PSPDFKit for Web 2018.4 features](/guides/web/release-notes/2018-4.md)
- [Explore new features in PSPDFKit 2018.5](/guides/web/release-notes/2018-5.md)
- [Explore PSPDFKit for Web 2018.6 enhancements](/guides/web/release-notes/2018-6.md)
- [Explore the new features in PSPDFKit 2018.7](/guides/web/release-notes/2018-7.md)
- [Key updates in PSPDFKit for Web 2019.1](/guides/web/release-notes/2019-1.md)
- [2019 2](/guides/web/release-notes/2019-2.md)
- [PSPDFKit for Web 2019.3 migration highlights](/guides/web/release-notes/2019-3.md)
- [Essential updates in PSPDFKit for Web 2019.4](/guides/web/release-notes/2019-4.md)
- [PSPDFKit for Web 2019.5 migration insights](/guides/web/release-notes/2019-5.md)
- [Key changes in PSPDFKit for Web 2020.1](/guides/web/release-notes/2020-1.md)
- [Seamless migration to PSPDFKit for Web 2020.2](/guides/web/release-notes/2020-2.md)
- [Upgrade to PSPDFKit Web 2020.3 seamlessly](/guides/web/release-notes/2020-3.md)
- [PSPDFKit Web and Server 2020.4 migration update](/guides/web/release-notes/2020-4.md)
- [Unified CRUD API enhancements for easy migration](/guides/web/release-notes/2020-5.md)
- [PSPDFKit Web 2020.6 migration insights](/guides/web/release-notes/2020-6.md)
- [Upgrade to PSPDFKit for Web 2021.1 with ease](/guides/web/release-notes/2021-1.md)
- [Seamlessly migrate to PSPDFKit for Web 2021.2](/guides/web/release-notes/2021-2.md)
- [2021 3](/guides/web/release-notes/2021-3.md)
- [PSPDFKit 2021.4 migration guide for seamless updates](/guides/web/release-notes/2021-4.md)
- [Migration guide for PSPDFKit 2021.5](/guides/web/release-notes/2021-5.md)
- [2021 6](/guides/web/release-notes/2021-6.md)
- [PSPDFKit 2022.1.1 migration changes](/guides/web/release-notes/2022-1.md)
- [Enhancements in PSPDFKit for Web 2022.2](/guides/web/release-notes/2022-2.md)
- [Explore the new features of PSPDFKit for Web 2022.3](/guides/web/release-notes/2022-3.md)
- [PSPDFKit for Web 2022.4 migration overview](/guides/web/release-notes/2022-4.md)
- [Key improvements in PSPDFKit for Web 2022.5](/guides/web/release-notes/2022-5.md)
- [Discover the key updates in PSPDFKit for Web 2023.1](/guides/web/release-notes/2023-1.md)
- [PSPDFKit 2023.2 migration and updates](/guides/web/release-notes/2023-2.md)
- [Key updates in PSPDFKit for Web 2023.3](/guides/web/release-notes/2023-3.md)
- [Explore key updates in PSPDFKit for Web 2023.4](/guides/web/release-notes/2023-4.md)
- [Key updates in PSPDFKit for Web 2023.5](/guides/web/release-notes/2023-5.md)
- [Essential Nutrient Web SDK 2024.1 migration tips](/guides/web/release-notes/2024-1.md)
- [2024 2](/guides/web/release-notes/2024-2.md)
- [2024 3](/guides/web/release-notes/2024-3.md)
- [2024 4](/guides/web/release-notes/2024-4.md)
- [2024 5](/guides/web/release-notes/2024-5.md)
- [2024 7](/guides/web/release-notes/2024-7.md)
- [2024 8](/guides/web/release-notes/2024-8.md)
- [Upgrading Nutrient Web SDK](/guides/web/release-notes/upgrading.md)

