<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Nutrient Web Releases</title>
        <link>https://www.nutrient.io/guides/web/</link>
        <description>Release notes for Nutrient Web SDK</description>
        <lastBuildDate>Wed, 07 Oct 2026 00:00:00 GMT</lastBuildDate>
    <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en-US</language>
        <atom:link href="https://www.nutrient.io/guides/web/release-notes/feed.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2024.8 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2024-8/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2024-8/</guid>
            <pubDate>Thu, 01 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Nutrient Web SDK 2024.8 release notes. New features, API changes, performance improvements, and bug fixes in this version.]]></description>
            <content:encoded><![CDATA[This release includes updates to the Web SDK’s user interface, with the following UI sections migrated:

- Ink annotation toolbar
- Text and Callout annotation toolbar
- Annotations sidebar
- Outline sidebar

Most customizations will continue to work as before, but if you notice anything unexpected and you were using CSS classes or CSS variables for customization, our Baseline UI migration guide offers helpful tips and guidance.

[bui-migration]: /guides/web/migration-guides/baseline-ui-migration-guide/

Nutrient Web SDK 2024.8 release notes. New features, API changes, performance improvements, and bug fixes in this version.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2024.7 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2024-7/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2024-7/</guid>
            <pubDate>Mon, 01 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Nutrient Web SDK 2024.7 release notes. New features, API changes, performance improvements, and bug fixes in this version.]]></description>
            <content:encoded><![CDATA[Nutrient Web SDK 2024.7 release notes. New features, API changes, performance improvements, and bug fixes in this version.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2024.5 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2024-5/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2024-5/</guid>
            <pubDate>Wed, 01 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Nutrient Web SDK 2024.5 release notes. New features, API changes, performance improvements, and bug fixes in this version.]]></description>
            <content:encoded><![CDATA[Nutrient Web SDK 2024.5 release notes. New features, API changes, performance improvements, and bug fixes in this version.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2024.4 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2024-4/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2024-4/</guid>
            <pubDate>Mon, 01 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Nutrient Web SDK 2024.4 release notes. New features, API changes, performance improvements, and bug fixes in this version.]]></description>
            <content:encoded><![CDATA[Nutrient Web SDK 2024.4 release notes. New features, API changes, performance improvements, and bug fixes in this version.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2024.3 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2024-3/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2024-3/</guid>
            <pubDate>Fri, 01 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover the latest updates in Nutrient Web SDK 2024.3, including browser support changes and essential implementation guidelines for users.]]></description>
            <content:encoded><![CDATA[Discover the latest updates in Nutrient Web SDK 2024.3, including browser support changes and essential implementation guidelines for users.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2024.2 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2024-2/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2024-2/</guid>
            <pubDate>Thu, 01 Feb 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover the breaking changes in Nutrient Web SDK 2024.2, including the new clipboard annotation API. Ensure your implementation is up to date.]]></description>
            <content:encoded><![CDATA[Discover the breaking changes in Nutrient Web SDK 2024.2, including the new clipboard annotation API. Ensure your implementation is up to date.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2024.1 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2024-1/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2024-1/</guid>
            <pubDate>Mon, 01 Jan 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn key updates and API changes in Nutrient Web SDK 2024.1. Ensure a smooth migration with our comprehensive guide to new features.]]></description>
            <content:encoded><![CDATA[Learn key updates and API changes in Nutrient Web SDK 2024.1. Ensure a smooth migration with our comprehensive guide to new features.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2023.5 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2023-5/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2023-5/</guid>
            <pubDate>Mon, 01 May 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore key updates in the PSPDFKit for Web 2023.5 migration, including new features, bug fixes, and implementation advice.]]></description>
            <content:encoded><![CDATA[Explore key updates in the PSPDFKit for Web 2023.5 migration, including new features, bug fixes, and implementation advice.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2023.4 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2023-4/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2023-4/</guid>
            <pubDate>Sat, 01 Apr 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the new APIs, bug fixes, and important migration steps in PSPDFKit for Web 2023.4.]]></description>
            <content:encoded><![CDATA[Learn about the new APIs, bug fixes, and important migration steps in PSPDFKit for Web 2023.4.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2023.3 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2023-3/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2023-3/</guid>
            <pubDate>Wed, 01 Mar 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore key API changes and bug fixes in the PSPDFKit for Web 2023.3 migration guide. Update your implementation for improved performance.]]></description>
            <content:encoded><![CDATA[Explore key API changes and bug fixes in the PSPDFKit for Web 2023.3 migration guide. Update your implementation for improved performance.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2023.2 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2023-2/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2023-2/</guid>
            <pubDate>Wed, 01 Feb 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore key changes in PSPDFKit for Web 2023.2, including API updates and migration steps to optimize your implementation.]]></description>
            <content:encoded><![CDATA[Explore key changes in PSPDFKit for Web 2023.2, including API updates and migration steps to optimize your implementation.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2023.1 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2023-1/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2023-1/</guid>
            <pubDate>Sun, 01 Jan 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the new features, bug fixes, and changes in PSPDFKit for Web 2023.1 migration guide to enhance your implementation and usage.]]></description>
            <content:encoded><![CDATA[Learn about the new features, bug fixes, and changes in PSPDFKit for Web 2023.1 migration guide to enhance your implementation and usage.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2022.5 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2022-5/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2022-5/</guid>
            <pubDate>Sun, 01 May 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore new APIs and fixes in PSPDFKit for Web 2022.5, including IE11 support removal and improved text selection capabilities.]]></description>
            <content:encoded><![CDATA[Explore new APIs and fixes in PSPDFKit for Web 2022.5, including IE11 support removal and improved text selection capabilities.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2022.4 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2022-4/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2022-4/</guid>
            <pubDate>Fri, 01 Apr 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about PSPDFKit for Web 2022.4 features, bug fixes, and the shift away from Internet Explorer 11 support. Migrate your server with confidence!]]></description>
            <content:encoded><![CDATA[Learn about PSPDFKit for Web 2022.4 features, bug fixes, and the shift away from Internet Explorer 11 support. Migrate your server with confidence!]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2022.3 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2022-3/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2022-3/</guid>
            <pubDate>Tue, 01 Mar 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the updates in PSPDFKit for Web 2022.3, including persistent icon behavior and crucial bug fixes. Ensure your implementation is up to date!]]></description>
            <content:encoded><![CDATA[Learn about the updates in PSPDFKit for Web 2022.3, including persistent icon behavior and crucial bug fixes. Ensure your implementation is up to date!]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2022.2 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2022-2/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2022-2/</guid>
            <pubDate>Tue, 01 Feb 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover new features and fixes in PSPDFKit for Web 2022.2, including text selection improvements for rotated documents.]]></description>
            <content:encoded><![CDATA[Discover new features and fixes in PSPDFKit for Web 2022.2, including text selection improvements for rotated documents.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2022.1 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2022-1/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2022-1/</guid>
            <pubDate>Sat, 01 Jan 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the latest API updates in PSPDFKit 2022.1.1 and ensure a smooth transition for your implementation.]]></description>
            <content:encoded><![CDATA[Version 2022.1.0 contains a bug that was immediately fixed in the next version, 2022.1.1. Use version 2022.1.1 instead of 2022.1.0.
{% /alert %}

PSPDFKit for Web 2022.1 introduces several API changes. We recommend verifying your implementation to check if it needs updating.

Explore the latest API updates in PSPDFKit 2022.1.1 and ensure a smooth transition for your implementation.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2021.6 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2021-6/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2021-6/</guid>
            <pubDate>Tue, 01 Jun 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the API changes and migration steps for PSPDFKit for Web 2021.6, including updates to annotation, bookmark, and form field methods.]]></description>
            <content:encoded><![CDATA[- Removes `Instance#createAnnotation`, `Instance#createBookmark`, and `Instance#createFormField` in favor of `Instance#create`.
- Removes `Instance#saveAnnotations`, `Instance#saveBookmarks`, `Instance#saveComments`, `Instance#saveFormFields`, and `Instance#saveFormFieldValues` in favor of [`save`].
- Removes `Instance#updateAnnotation`, `Instance#updateBookmark`, and `Instance#updateFormField` in favor of `Instance#update`.
- Removes `Instance#deleteAnnotations`, `Instance#deletebookmark`, and `Instance#deleteFormField` in favor of `Instance#delete`.
- Removes `Instance#ensureAnnotationSaved`, `Instance#ensureBookmarkSaved`, and `Instance#ensureFormFieldSaved` in favor of `Instance#ensureChangesSaved`.
- Removes `Instance#hasUnsavedAnnotations`, `Instance#hasUnsavedBookmarks`, `Instance#hasUnsavedComments`, `Instance#hasUnsavedFormFieldValues`, and `Instance#hasUnsavedFormFields` in favor of `Instance#hasUnsavedChanges`.

Note that some of these deprecated APIs returned a single result, but the new API will always return an array. Make sure any of your code that relied on this behavior accesses the first element in the array.

Below is an example of how to use the new `Instance#update` API with a single annotation:

```js
instance.update([annotation]).then((annotations) => {
  const savedAnnotation = annotations[0];
});
```

If you used to call `Instance#createAnnotation` to create a widget, and then attached it to a form
using `Instance#createFormField`, you’ll now need to create the form field first.

You’ll also need to generate and set the widget’s ID using `PSPDFKit#generateInstantId` so that you can reference the widget from the form field before it’s added to the document.

Here’s an example of how you can do this using the new `Instance.html#create` API:

```js
const annotation = new NutrientViewer.Annotations.WidgetAnnotation({
  id: NutrientViewer.generateInstantId(),
  pageIndex: 0,
  formFieldName: "name",
  boundingBox: new NutrientViewer.Geometry.Rect({
    left: 10,
    top: 20,
    width: 60,
    height: 40
  })
});

const form = new NutrientViewer.FormFields.TextFormField({
  name: "name",
  annotationIds: NutrientViewer.Immutable.List([annotation.id]),
  label: "A label"
});

instance.create([annotation, form]);
```

By default, this makes signatures respect their aspect ratio when being resized by their corner handles. To opt out of this and go back to the old behavior, you can use the new `onAnnotationResizeStart` callback option:

```js
NutrientViewer.load({
  onAnnotationResizeStart: (event) => {
    if (event.annotation.isSignature && !event.isShiftPressed) {
      return {
        maintainAspectRatio: false
      };
    }

    return undefined;
  }
});
```

For a full list of changes, check out the changelog.

Learn about the API changes and migration steps for PSPDFKit for Web 2021.6, including updates to annotation, bookmark, and form field methods.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2021.5 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2021-5/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2021-5/</guid>
            <pubDate>Sat, 01 May 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the new AP stream rendering in PSPDFKit 2021.5 and understand important migration steps for improved performance in older browsers.]]></description>
            <content:encoded><![CDATA[Performance of initial AP stream rendering in Server mode has been improved as well, except for in some older browsers — namely old Safari versions and IE11.

{% alert type="warning" line="multi-line" %}
Internet Explorer 11 is no longer supported in our Web SDK as of version 2022.5. Edge 18 is no longer supported in our Web SDK as of version 2023.2.
{% /alert %}

In those cases, annotation rendering in Server mode may appear slower, especially if AP stream rendering wasn’t enabled before.

As a workaround, disabling AP stream rendering for those browsers in the configuration is the recommended approach:

```js
// `isIE11` and `isOldSafari` are placeholders for browser detection flags.
NutrientViewer.load({
  isAPStreamRendered: () => !isIE11 && !isOldSafari
});
```

For a full list of changes, check out the changelog.

Explore the new AP stream rendering in PSPDFKit 2021.5 and understand important migration steps for improved performance in older browsers.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2021.4 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2021-4/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2021-4/</guid>
            <pubDate>Thu, 01 Apr 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the new features of PSPDFKit 2021.4, including default JavaScript actions and improved TypeScript declarations for better integration and accuracy.]]></description>
            <content:encoded><![CDATA[If this setting affects your integration, you can restore the previous behavior by setting the option to `false` before calling `NutrientViewer.load()`:

```js
NutrientViewer.Options.PDF_JAVASCRIPT = false;
NutrientViewer.load(configuration);
```

We completely changed the way we generate TypeScript declarations to make them more powerful and accurate. The internal API declarations are no longer exported, so if you were using those, it might lead to errors during the build step. This shouldn’t affect you if you weren’t using the types of internal APIs. If you still want to use internal types, most of them can be formed using the combination of `typeof` and utility types.

Before:

```js
import Instance from "pspdfkit/dist/types/typescript/Instance";
```

After:

```js
type Instance = InstanceType<typeof NutrientViewer.Instance>;
```

Some of the frequently used types are:

```js
type Instance = InstanceType<typeof NutrientViewer.Instance>;
type Rect = InstanceType<typeof NutrientViewer.Geometry.Rect>;
type Color = InstanceType<typeof NutrientViewer.Color>;
type Annotation = InstanceType<typeof NutrientViewer.Annotations.Annotation>;
type TextSelection = InstanceType<typeof NutrientViewer.TextSelection>;
type ToolbarItems = InstanceType<typeof NutrientViewer.Instance>["toolbarItems"];
type List = ReturnType<typeof NutrientViewer.Immutable.List>;

type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;
type AnnotationsList = Awaited<ReturnType<Instance["getAnnotations"]>>;
```

We’re exploring ways to make this experience better in our upcoming releases.

For a full list of changes, check out the changelog.

Explore the new features of PSPDFKit 2021.4, including default JavaScript actions and improved TypeScript declarations for better integration and accuracy.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2021.3 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2021-3/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2021-3/</guid>
            <pubDate>Mon, 01 Mar 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover the latest PSPDFKit 2021.3 update with API renaming from ink signatures to stored signatures, enhancing clarity and usability.]]></description>
            <content:encoded><![CDATA[- The `NutrientViewer.Configuration#populateInkSignatures` option was renamed to `NutrientViewer.Configuration#populateStoredSignatures`.
- The `NutrientViewer.Instance#getInkSignatures` method was renamed to `NutrientViewer.Instance#getStoredSignatures`.
- The `NutrientViewer.Instance#setInkSignatures` method was renamed to `NutrientViewer.Instance#setStoredSignatures`.
- The `NutrientViewer.InteractionMode.INK_SIGNATURE` value was renamed to `NutrientViewer.InteractionMode.SIGNATURE`.
- The `inkSignatures.create`, `inkSignatures.update`, `inkSignatures.delete`, and `inkSignatures.change` events were renamed to `storedSignatures.create`, `storedSignatures.update`, `storedSignatures.delete`, and `storedSignatures.change`.
- The `ink-signature` toolbar item, which was part of `NutrientViewer.defaultToolbarItems`, was renamed to `signature`.

All of the former APIs will keep working as expected, but a warning will be logged into the console when used. Migrate to the new names since the deprecated ones will be removed as part of the next major release.

Signature APIs that previously only supported ink annotations now also support image annotations:

- `NutrientViewer.Configuration#populateStoredSignatures` and `NutrientViewer.Instance#setStoredSignatures` now also support using `NutrientViewer.Annotation.ImageAnnotation` instances, along with `NutrientViewer.Annotation.InkAnnotation` ones. They’ll also be presented on the signature picking UI.
- `NutrientViewer.Instance#getStoredSignatures` can return `NutrientViewer.Annotation.ImageAnnotation` instances in addition to `NutrientViewer.Annotation.InkAnnotation` ones.
- The `storedSignatures.create`, `storedSignatures.update`, and `storedSignatures.delete` events can return `NutrientViewer.Annotation.ImageAnnotation`instances in addition to `NutrientViewer.Annotation.InkAnnotation` ones.

For a full list of changes, check out the changelog.

Discover the latest PSPDFKit 2021.3 update with API renaming from ink signatures to stored signatures, enhancing clarity and usability.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Web 2021.2 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2021-2/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2021-2/</guid>
            <pubDate>Mon, 01 Feb 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the new PDF Generation feature and migration tips in PSPDFKit for Web 2021.2. Discover all updates in the latest changelog.]]></description>
            <content:encoded><![CDATA[For a full list of changes, check out the changelog.

Explore the new PDF Generation feature and migration tips in PSPDFKit for Web 2021.2. Discover all updates in the latest changelog.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2021.1 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2021-1/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2021-1/</guid>
            <pubDate>Fri, 01 Jan 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Navigate changes in PSPDFKit for Web 2021.1 and optimize your configuration for new features like the Export PDF button. Update your migration strategy now!]]></description>
            <content:encoded><![CDATA[### Notable changes

- (#25320) This release removes the `NutrientViewer.Configuration#disableIndexedDBCaching` option. The reason for this is browsers dropped plans to ship this caching strategy, and instead, the caching of WebAssembly modules will follow regular HTTP cache rules.

  Now, there’s no longer a way to enable IndexedDB caching, so `disableIndexedDBCaching` isn’t necessary and doesn’t have any effect.

  This flag will be entirely removed in a future release of PSPDFKit for Web, so it’s recommended to remove it from the `NutrientViewer.Configuration` object when creating a PSPDFKit instance.

  For more information about WebAssembly modules caching, refer to the MDN page, this Mozilla bug entry, and this WebAssembly spec issue.

- (#26594) This release ships with a new toolbar button, Export PDF. If you don’t want to use it, remove the `export-pdf` button type from the default toolbar items when loading PSPDFKit:

  ```js
  const toolbarItems = NutrientViewer.defaultToolbarItems.filter(it => {
    return it.type !== "export-pdf";
  });
  
  NutrientViewer.load({ ...configuration, toolbarItems });
  ```

- (#25309) This release slightly changes the behavior of specifying a range of pages to search within when using the `NutrientViewer.Instance#search()` API. Previously, specifying both `startPageIndex` and `endPageIndex` made search results include matches from the start page index up until the end page index, without including those from the last page. Now, search results also include those from the end page index that’s specified.

To keep the previous behavior, you’ll instead need to call `NutrientViewer.Instance#search`, passing `endPageIndex - 1` as the `endPageIndex` property value.

- (#27856) You’ll no longer be allowed to change the `rootId` of a comment once it has been created. If you were updating the `rootId` before, make sure you create a new comment instead.
- (#27443) This release prevents setting `NutrientViewer.ViewState#interactionMode` to a value that enables annotation creation with the UI when in read-only mode (`NutrientViewer.ViewState#readOnly` is `true`). The new interaction mode set via `Instance#setViewState` is set as `null` in this case, and a warning is emitted to the console.

If you use PSPDFKit Server, make sure you read the 2021.1 server migration guide.

For a full list of changes, check out the changelog.

[pspdfkit for web 2021.1]: /blog/pspdfkit-web-2021-1-collaboration-permissions/
[mdn page]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
[mozilla bug]: https://bugzilla.mozilla.org/show_bug.cgi?id=1469395
[wasm issue]: https://github.com/WebAssembly/spec/issues/821
[`nutrientviewer.instance#search()`]: /api/web/classes/NutrientViewer.Instance.html#search
[2021.1 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[changelog]: /guides/web/changelog/#2021.1
[web sdk 2020.6 release notes]: /guides/web/release-notes/2020-6/

Navigate changes in PSPDFKit for Web 2021.1 and optimize your configuration for new features like the Export PDF button. Update your migration strategy now!]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2020.6 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2020-6/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2020-6/</guid>
            <pubDate>Mon, 01 Jun 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the key updates in PSPDFKit Web 2020.6, including a new default blue and migration tips for annotations and color presets.]]></description>
            <content:encoded><![CDATA[### Notable changes

- This release introduces a new blue color: `rgb(34, 147, 251)`. This new blue color will be used in the color picker instead of the old one, and it’ll be used as the default ink color (it affects ink annotations and shape annotations like rectangle and ellipse annotations, both of which are configurable).

  If you wish to see the old blue color in the color picker, you can amend the `NutrientViewer.Options.COLOR_PRESETS` object before `NutrientViewer.load()`:

  ```js
  const blue = {
    color: new NutrientViewer.Color({ r: 36, g: 131, b: 199 }),
    localization: {
      id: "customBlue",
      defaultMessage: "Custom blue",
      description: "custom blue"
    }
  };
  NutrientViewer.Options.COLOR_PRESETS = NutrientViewer.Options.COLOR_PRESETS.concat([
    blue
  ]);
  ```

  And here’s how to configure the old blue as the default ink color using the annotation presets:

  ```js
  const annotationPresets = NutrientViewer.defaultAnnotationPresets
  annotationPresets.ink = {
    ...annotationPresets.ink,
    strokeColor: NutrientViewer.Color.DARK_BLUE,
  }
  
  NutrientViewer.load({annotationPreset, ...})
  ```

- This release changes the way in which you can move an annotation using the UI. By default, annotations can only be moved inside page boundaries. If you want to disable this behavior and enable the previous behavior, use the following configuration option:

  ```js
  NutrientViewer.load({
    restrictAnnotationToPageBounds: false
  });
  ```

For a full list of changes, check out the changelog.

If you use PSPDFKit Server, make sure you read the 2020.6 server migration guide.

[pspdfkit for web 2020.6]: /blog/pspdfkit-for-web-adds-annotation-notes/
[2020.6 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[changelog]: /guides/web/changelog/#2020.6.0
[`nutrientviewer.options.color_presets`]: /api/web/variables/NutrientViewer.Options.COLOR_PRESETS.html
[annotation presets]: /api/web/interfaces/Configuration.html#annotationpresets
[web sdk 2020.5 release notes]: /guides/web/release-notes/2020-5/

Explore the key updates in PSPDFKit Web 2020.6, including a new default blue and migration tips for annotations and color presets.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2020.5 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2020-5/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2020-5/</guid>
            <pubDate>Fri, 01 May 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Easily migrate to the unified CRUD API in PSPDFKit 2020.5 with improved batch updates and streamlined object management for annotations and comments.]]></description>
            <content:encoded><![CDATA[### Notable changes

#### Unified CRUD API

- This release introduces a unified API for creating, updating, deleting, and saving objects:
  - `Instance#create`
  - `Instance#update`
  - `Instance#delete`
  - `Instance#ensureChangesSaved`

  These methods support a single change or an array of changes allowing batched updates. Each of them resolves with an array of resolved changes (created/updated/deleted/saved). Operations are performed even if some batched changes can’t be executed. In this case, the methods reject with an array containing the resolved changes or errors for failed changes.

  Supported change types are: annotations, bookmarks, form fields, form field values, and comments.

- Most existing `Instance` methods for performing modifications and saving objects have been deprecated:

| Deprecated Method                                                     | Replacement                       |
| --------------------------------------------------------------------- | --------------------------------- |
| `createAnnotation/FormField/Bookmark`                                 | `Instance#create`             |
| `updateAnnotation/FormField/Bookmark`                                 | `Instance#update`             |
| `deleteAnnotation/FormField/Bookmark`                                 | `Instance#delete`             |
| `hasUnsavedAnnotations/FormFields/FormFieldValues/Bookmarks/Comments` | `Instance#hasUnsavedChanges`  |
| `ensureAnnotation/FormField/BookmarkSaved`                            | `Instance#ensureChangesSaved` |
| `saveAnnotations/FormFields/FormFieldValues/Bookmarks/Comments`       | `Instance#save`               |

To migrate your existing use of CRUD-related methods, update the method name. If you’re using the result value, make sure to update this too since the new unified CRUD methods return an array of changes instead of a single change. For example:

```js
// Deprecated code:
const createdAnnotation = await instance.createAnnotation(newAnnotation);
console.log(`Created annotation with ID ${createdAnnotation.id}`);

// Should be replaced with:
const [createdAnnotation] = await instance.create(newAnnotation);
console.log(`Created annotation with ID ${createdAnnotation.id}`);
```

- `Instance#save` and `Instance#ensureChangesSaved` now report errors for some changes when a save fails.
- In contrast to the now-deprecated `Instance#createAnnotation`, `Instance#create` fails when creating a widget annotation without its associated form field. Make sure to create both in the same `create` method call:

  ```js
  const widget = new NutrientViewer.Annotations.WidgetAnnotation({
    id: NutrientViewer.generateInstantId(),
    pageIndex: 0,
    formFieldName: "MyFormField",
    boundingBox: new NutrientViewer.Geometry.Rect({
      left: 100,
      top: 75,
      width: 200,
      height: 80
    })
  });
  const formField = new NutrientViewer.FormFields.TextFormField({
    name: "MyFormField",
    annotationIds: NutrientViewer.Immutable.List([widget.id]),
    value: "Text shown in the form field"
  });
  
  instance.create([widget, formField]);
  ```

{% alert type="neutral-gray" line="single-line" %}
A created form field requires the widget annotation ID before the annotation is created. This means you must assign a unique UID for your widget annotation when using this new API. You can generate a proper UID via the newly introduced `PSPDFKit#generateInstantId`.
{% /alert %}

If you use PSPDFKit Server, make sure you read the 2020.5 server migration guide.

For a full list of changes, check out the changelog.

[2020.5 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[changelog]: /guides/web/changelog/#2020.5
[2020.4 migration guide]: /guides/product-archives-and-deprecated-solutions/
[`instance#createannotation`]: /api/web/classes/NutrientViewer.Instance.html#createannotation
[`pspdfkit#generateinstantid`]: /api/web/functions/NutrientViewer.generateInstantId.html
[pspdfkit for web 2020.5]: /blog/pspdfkit-for-web-introduces-new-crud-api/
[web sdk 2020.4 release notes]: /guides/web/release-notes/2020-4/
[`instance#create`]: /api/web/classes/NutrientViewer.Instance.html#create
[`instance#update`]: /api/web/classes/NutrientViewer.Instance.html#update
[`instance#delete`]: /api/web/classes/NutrientViewer.Instance.html#delete
[`instance#ensurechangessaved`]: /api/web/classes/NutrientViewer.Instance.html#ensurechangessaved
[`instance#hasunsavedchanges`]: /api/web/classes/NutrientViewer.Instance.html#hasunsavedchanges
[`instance#save`]: /api/web/classes/NutrientViewer.Instance.html#save

Easily migrate to the unified CRUD API in PSPDFKit 2020.5 with improved batch updates and streamlined object management for annotations and comments.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2020.4 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2020-4/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2020-4/</guid>
            <pubDate>Wed, 01 Apr 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the 2020.4 migration guide for PSPDFKit Web and Server. No web-related migration needed for 2020.4.]]></description>
            <content:encoded><![CDATA[If you use PSPDFKit Server, make sure you read the 2020.4 server migration guide.

[2020.4 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[web sdk 2020.3 release notes]: /guides/web/release-notes/2020-3/

Learn about the 2020.4 migration guide for PSPDFKit Web and Server. No web-related migration needed for 2020.4.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2020.3 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2020-3/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2020-3/</guid>
            <pubDate>Sun, 01 Mar 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the PSPDFKit Web 2020.3 migration guide with key updates and changes for a smooth integration experience.]]></description>
            <content:encoded><![CDATA[### Notable changes

- If you have a Digital Signatures license, signature widgets for digitally signed form fields will now be rendered using the appearance streams of their associated widgets, and they will not be interactive. This means you won’t be able to open the ink signature dialog by clicking on a widget. If you want to restore the old behavior and bring up the ink signature dialog when a widget is pressed, even if the form field is digitally signed, you will have to implement it manually by handling the `annotations.press` event and setting the `interactionMode` to `NutrientViewer.InteractionMode.INK_SIGNATURE`:

  ```javascript
  instance.addEventListener("annotations.press", () => {
    instance.setViewState(s =>
      s.set("interactionMode", NutrientViewer.InteractionMode.INK_SIGNATURE)
    );
  });
  ```

If you use PSPDFKit Server, make sure you read the 2020.3 migration guide.

For a full list of changes, check out the changelog.

[pspdfkit for web 2020.3]: /blog/pspdfkit-adds-redaction-and-improved-digital-signatures-to-web/
[changelog]: /guides/web/changelog/#2020.3
[2020.3 migration guide]: /guides/product-archives-and-deprecated-solutions/
[web sdk 2020.2 release notes]: /guides/web/release-notes/2020-2/

Explore the PSPDFKit Web 2020.3 migration guide with key updates and changes for a smooth integration experience.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2020.2 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2020-2/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2020-2/</guid>
            <pubDate>Sat, 01 Feb 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore essential migration tips and deprecated options in PSPDFKit for Web 2020.2 for a smooth upgrade experience.]]></description>
            <content:encoded><![CDATA[### Notable changes

- The `Configuration#pdf` configuration option for PSPDFKit for Web Standalone is deprecated.

With the introduction of Image Documents, the web Standalone `Configuration#pdf` option has been deprecated in favor of `Configuration#document`. As we are simply renaming the option, the behavior for PDFs remains the same, and no additional changes are required. The old option will be removed in 2020.3.

See the API documentation for more details.

- Properties deprecated in `2020.1` have been removed:
  - `NutrientViewer.I18n#localeData` — This property stopped working in `2020.1`, and a deprecation warning was shown when used. The warning will no longer be shown, and the property is removed, so it will just return `undefined` if accessed. Refer to the 2020.1 migration guide for details on how to migrate from this property.
  - `NutrientViewer.Annotations.RectangleAnnotation#cloudyBorderInsetRect` and `NutrientViewer.Annotations.EllipseAnnotation#cloudyBorderInsetRect` could still be used after `2020.1` with a warning. These properties will no longer work, they will return `undefined` if accessed, and no warning will be shown. Refer to the 2020.1 migration guide and the API documentation on `NutrientViewer.Annotations.RectangleAnnotation#cloudyBorderInset` and `NutrientViewer.Annotations.EllipseAnnotation#cloudyBorderInset` for details on how to migrate from these properties.

If you use PSPDFKit Server, make sure you read the 2020.2 migration guide.

For a full list of changes, check out the changelog.

[pspdfkit for web 2020.2]: /blog/pspdfkit-web-2020-2/
[more details]: /api/web/interfaces/Configuration.html#document
[changelog]: /guides/web/changelog/#2020.2
[2020.2 migration guide]: /guides/product-archives-and-deprecated-solutions/
[2020.1 migration guide]: /guides/web/migration-guides/2020-1-migration-guide/
[`nutrientviewer.annotations.rectangleannotation#cloudyborderinset`]: /api/web/classes/NutrientViewer.Annotations.RectangleAnnotation.html#cloudyborderinset
[`nutrientviewer.annotations.ellipseannotation#cloudyborderinset`]: /api/web/classes/NutrientViewer.Annotations.EllipseAnnotation.html#cloudyborderinset
[web sdk 2020.1 release notes]: /guides/web/release-notes/2020-1/

Explore essential migration tips and deprecated options in PSPDFKit for Web 2020.2 for a smooth upgrade experience.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2020.1 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2020-1/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2020-1/</guid>
            <pubDate>Wed, 01 Jan 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the significant updates in PSPDFKit Web 2020.1, including localization changes and deprecated features for seamless migration.]]></description>
            <content:encoded><![CDATA[### Notable changes

- `NutrientViewer.I18n#localeData` has been deprecated because we have adopted React Intl version `3.x.x` changes. This version has dropped support for providing custom localization data in favor of using the standard `Intl` Web API for pluralization and other localization rules, which means that you no longer need to provide these rules if you want to support additional locales.

  This also means you will no longer be able to provide localization rules for locales not supported by the browser, but considering the large number of locales supported by modern browsers, this should not pose a problem.

  Browsers that do not support the `Intl` API (like IE11 and Safari < 13) will include a polyfill for `Intl.PluralRules`, as well as an individual polyfill for each of the supported locales. If you want to continue 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");
  ```

{% alert type="warning" line="multi-line" %}
Internet Explorer 11 is no longer supported in our Web SDK as of version 2022.5. Edge 18 is no longer supported in our Web SDK as of version 2023.2.
{% /alert %}

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

{% tabs variant="underline-accent" %}
{% tabitem label="YARN" %}
```yarn
  yarn add @formatjs/intl-pluralrules
```
{% /tabitem %}

{% tabitem label="NPM" %}
```npm
  npm i @formatjs/intl-pluralrules
```
{% /tabitem %}
{% /tabs %}

- We reworked the font sizing for the entire application, and this might result in some UI differences. In particular, if you use custom CSS for your UI, check your application to ensure the new setup doesn’t affect your integration negatively.
- `NutrientViewer.Annotations.RectangleAnnotation#cloudyBorderInsetRect` and `NutrientViewer.Annotations.EllipseAnnotation#cloudyBorderInsetRect` are now deprecated, and they have been replaced by the new `NutrientViewer.Annotations.RectangleAnnotation#cloudyBorderInset` and `NutrientViewer.Annotations.EllipseAnnotation#cloudyBorderInset` properties, which use a new `NutrientViewer.Geometry.Inset` type instead of `NutrientViewer.Geometry.Rect`. Thanks to this change, you will not need to update the annotation whenever the bounding box changes, as was the case with the now deprecated `cloudyBorderInsetRect` property.

  It will still be possible to use `NutrientViewer.Annotations.RectangleAnnotation#cloudyBorderInsetRect` in the constructor, where it will be transformed into a `NutrientViewer.Geometry.Inset` and used to set `NutrientViewer.Annotations.RectangleAnnotation#cloudyBorderInset` instead. `cloudyBorderInsetRect` can still be read too, in which case a snapshot value will be returned, which is the result of adding the inset values from `cloudyBorderInset` to the current bounding box.

A deprecation warning will be shown each time `cloudyBorderInsetRect` is used. In the next major version, `cloudyBorderInsetRect` will finally be removed.

If you use the `cloudyBorderInsetRect` property in your code, you will have to update it so it does not break once the property is removed in the next major version.

Also, when you create a new rectangle or ellipse annotation with the `cloudyBorderIntensity` property set and there is no `cloudyBorderInset` or `cloudyBorderInsetRect` defined, a default `cloudyBorderInset` will be applied with values following this formula:

```js
const inset = 4.5 * cloudyBorderIntensity + strokeWidth / 2;
```

This default `cloudyBorderInset` value ensures that the cloudy border is not cropped and that it’s just wide enough for the cloudy border to fit in it. If you wish to set a `cloudyBorderInset` with `0` values, do it explicitly instead, using the following:

```js
const inset = new NutrientViewer.Geometry.Inset({
  left: 0,
  top: 0,
  right: 0,
  bottom: 0
});
```

Or, to make it less verbose, use the utility static class method `NutrientViewer.Geometry.Inset#fromValue`:

```js
const inset = NutrientViewer.Geometry.Inset.fromValue(0);
```

- `event.formField` has been removed from the documentation of `NutrientViewer.AnnotationsFocusEvent` and `NutrientViewer.AnnotationsBlurEvent`. It has never been part of the event payload, and this change only affects the aforementioned documentation, so it cannot break your implementation in any way. However, if you were relying on this, you may need to review your event listener logic in case the absence of this `event.formField` object may have been affecting its behavior. If you think you still need this object, you can easily get the `formField` associated with a particular annotation by using the following code:

  ```javascript
  instance.addEventListener("annotations.blur", event => {
    instance.getFormFields().then(formFields => {
      const formField = formFields.find(
        formField => formField.name === event.annotation.formFieldName
      );
      console.log(formField);
    });
  });
  ```

  If you are using `event.formField`, here is the change you need to make:

  **Before**

  ```javascript
  instance.addEventListener("annotations.focus", event => {
    console.log(event.formField);
  });
  
  instance.addEventListener("annotations.blur", event => {
    console.log(event.formField);
  });
  ```

  **After**

  ```javascript
  instance.addEventListener("annotations.focus", event => {
    instance.getFormFields().then(formFields => {
      const formField = formFields.find(
        formField => formField.name === event.annotation.formFieldName
      );
      console.log(formField);
    });
  });
  
  instance.addEventListener("annotations.blur", event => {
    instance.getFormFields().then(formFields => {
      const formField = formFields.find(
        formField => formField.name === event.annotation.formFieldName
      );
      console.log(formField);
    });
  });
  ```

- When the Digital Signatures component is included in the license, `NutrientViewer.Instance#exportPDF` will export signed documents as incrementally saved by default so as to prevent modifying signed data, which would invalidate the document’s digital signatures. However, setting the `incremental` flag to `false` will override this behavior.

  If the Digital Signatures component is not included in the license, the former behavior will be followed and signed documents will be exported as fully saved by default. In order to prevent signed data corruption in this case, the `incremental` flag should be explicitly set:

  ```js
  instance.exportPDF({ incremental: true });
  ```

- Previously, the object returned by `NutrientViewer.ViewState#viewportPadding` had the `vertical` value under the `horizontal` property and vice versa. This has been now fixed. If you were relying on the previous returned value, you will need to adjust your implementation accordingly.
- The order in which annotations are rendered has been modified. In previous versions, annotations of the same type would be rendered in the same layer, in the following order from back to front:
  - Text markup
  - Link
  - Text
  - Widget
  - Stamp
  - Image
  - Ink
  - Shape
  - Note

  Beginning with the current release, annotations will be rendered in the same order they are in the document, regardless of their type. New annotations will always be rendered on top of the last one that has been added.

  If your implementation relies on the former annotation rendering order, you may need to rearrange the order in which annotations are created so as to continue obtaining the same result.

  You would need to first create the annotations that you want to be rendered in the background, followed by the ones that you want to be rendered in the foreground. For example: First create text annotations, then stamp annotations, then ink and shape annotations, in that order. This way, your annotations will keep rendering in the order they had with the former behavior.

  If your annotations never overlap, this change will probably not affect your implementation at all.

- The note annotation icon in the main toolbar has been updated.

If you use PSPDFKit Server, make sure you read the 2020.1 migration guide.

For a full list of changes, check out the changelog.

[pspdfkit for web 2020.1]: /blog/pspdfkit-web-2020-1/
[`nutrientviewer.annotations.rectangleannotation#cloudyborderinsetrect`]: /api/web/classes/NutrientViewer.Annotations.RectangleAnnotation.html#cloudyborderinsetrect
[`nutrientviewer.annotations.rectangleannotation#cloudyborderinset`]: /api/web/classes/NutrientViewer.Annotations.RectangleAnnotation.html#cloudyborderinset
[`nutrientviewer.annotations.ellipseannotation#cloudyborderinsetrect`]: /api/web/classes/NutrientViewer.Annotations.EllipseAnnotation.html#cloudyborderinsetrect
[`nutrientviewer.annotations.ellipseannotation#cloudyborderinset`]: /api/web/classes/NutrientViewer.Annotations.EllipseAnnotation.html#cloudyborderinset
[`nutrientviewer.geometry.inset`]: /api/web/classes/NutrientViewer.Geometry.Inset.html
[`nutrientviewer.geometry.rect`]: /api/web/classes/NutrientViewer.Geometry.Rect.html
[`nutrientviewer.geometry.inset#fromvalue`]: /api/web/classes/NutrientViewer.Geometry.Inset.html#fromvalue
[`nutrientviewer.instance#exportpdf`]: /api/web/classes/NutrientViewer.Instance.html#exportpdf
[`nutrientviewer.viewstate#viewportpadding`]: /api/web/classes/NutrientViewer.ViewState.html#viewportpadding
[changelog]: /guides/web/changelog/#2020.1
[2020.1 migration guide]: /guides/product-archives-and-deprecated-solutions/
[react intl]: https://github.com/formatjs/react-intl
[standard `intl` web api]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl
[web sdk 2019.5 release notes]: /guides/web/release-notes/2019-5/

Explore the significant updates in PSPDFKit Web 2020.1, including localization changes and deprecated features for seamless migration.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2019.5 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2019-5/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2019-5/</guid>
            <pubDate>Wed, 01 May 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the 2019.5 migration guide for PSPDFKit for Web. No web migration needed, check changelog and server guide for updates.]]></description>
            <content:encoded><![CDATA[If you use PSPDFKit Server, make sure you read the 2019.5 server migration guide.

For a full list of changes, check out the changelog.

[pspdfkit for web 2019.5]: /blog/pspdfkit-web-2019-5/
[2019.5 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[changelog]: /guides/web/changelog/#2019.5
[web sdk 2019.4 release notes]: /guides/web/release-notes/2019-4/

Explore the 2019.5 migration guide for PSPDFKit for Web. No web migration needed, check changelog and server guide for updates.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2019.4 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2019-4/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2019-4/</guid>
            <pubDate>Mon, 01 Apr 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore key enhancements in PSPDFKit for Web 2019.4, including UI changes, a new Document Editor, and migration tips for seamless adaptation.]]></description>
            <content:encoded><![CDATA[### Notable changes

- We have changed our default UI to use a bright toolbar by default. Some changes might be necessary if you have used custom CSS that depended upon the dark toolbar, which is available by selecting `NutrientViewer.Theme.DARK` in `NutrientViewer.Configuration#theme`.
- A new Document Editor component has been implemented. If your license includes the document editing component, a new toolbar button that gives you access to this UI feature will be available in the main toolbar. You may need to update your toolbar items handling if your implementation depends on the toolbar items’ default configuration (see `NutrientViewer.defaultToolbarItems`).
- We updated the naming schema of our additional chunks delivered via the `pspdfkit-lib/` folder. The new names will now have prefixes you can use to preload specific parts of the app if necessary. Some examples include:
  - `pspdfkit-lib/chunk-locale-<locale>-*.js` files are used for internationalization files, e.g. `pspdfkit-lib/chunk-locale-de-*.js` for the German localization.
  - `chunk-standalone-*.js` is for all Standalone-specific artifacts.
  - `chunk-server-*.js` is for all Server-specific artifacts.

Note that the last part of the file name is still a hash of its content. This ensures we don’t run into caching issues when artifacts are updated.

- The icons in the toolbar were changed in order to shrink the toolbar height. Additionally, the icon size changed from 18x18&nbsp;px to 24x24&nbsp;px.
- The WebAssembly and asm.js artifacts now have a content hash as part of the file name. This allows you to configure a long-term caching strategy and make use of advanced features like WASM code caching. The affected files are:
  - `pspdfkit-lib/pspdfkit.wasm` ➡️ `pspdfkit-lib/pspdfkit-<hash>.wasm`
  - `pspdfkit-lib/pspdfkit.wasm.js` ➡️ `pspdfkit-lib/pspdfkit-<hash>.wasm.js`
  - `pspdfkit-lib/pspdfkit.asm.js` ➡️ `pspdfkit-lib/pspdfkit-<hash>.asm.js`
  - `pspdfkit-lib/pspdfkit.asm.js.mem` ➡️ `pspdfkit-lib/pspdfkit-<hash>.asm.js.mem`
- The thumbnail sidebar now comes with a changed layout. All public CSS classes can still be used to customize the styling:
  - `.PSPDFKit-Sidebar-Thumbnails-Page`
  - `.PSPDFKit-Sidebar-Thumbnails-Page-Image`
  - `.PSPDFKit-Sidebar-Thumbnails-Page-Label`
  - `.PSPDFKit-Sidebar-Thumbnails-Page-Selected`

If you use PSPDFKit Server, make sure you read the 2019.4 server migration guide.

For a full list of changes, check out the changelog.

[pspdfkit for web 2019.4]: /blog/pspdfkit-web-2019-4/
[wasm code caching]: https://v8.dev/blog/wasm-code-caching
[changelog]: /guides/web/changelog/#2019.4
[2019.4 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[`nutrientviewer.defaulttoolbaritems`]: /api/web/variables/NutrientViewer.defaultToolbarItems.html
[`nutrientviewer.configuration#theme`]: /api/web/interfaces/Configuration.html#theme
[web sdk 2019.3 release notes]: /guides/web/release-notes/2019-3/

Explore key enhancements in PSPDFKit for Web 2019.4, including UI changes, a new Document Editor, and migration tips for seamless adaptation.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2019.3 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2019-3/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2019-3/</guid>
            <pubDate>Fri, 01 Mar 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the key updates in PSPDFKit for Web 2019.3, including annotation changes and migration tips for seamless integration.]]></description>
            <content:encoded><![CDATA[### Notable changes

- The default minimum ink and shape annotations sizes, `NutrientViewer.Options.MIN_INK_ANNOTATION_SIZE` and `NutrientViewer.Options.MIN_SHAPE_ANNOTATION_SIZE`, have been reduced from `128` to `16`. The former value was too big for several use cases. If your code relies on the former value, you can set it before the first `NutrientViewer.load()` call: `NutrientViewer.Options.MIN_INK_ANNOTATION_SIZE = 128` and `NutrientViewer.Options.MIN_SHAPE_ANNOTATION_SIZE = 128`.
- While creating an ink annotation with the UI, new lines may be split into a new annotation if the new line starting point is too distant from the rest of the annotation points, and/or some time has passed since the last point was drawn, especially if the annotation already contains more than a certain amount of lines (over 50).
- The popover’s HTML structure has changed. Now the arrow element and the popover content are sibling elements. These elements are wrapped with the specific popover class name to enable targeted overrides, e.g. `.PSPDFKit-Popover-Annotation-Tooltip .PSPDFKit-Popover {}` and `.PSPDFKit-Popover-Annotation-Tooltip .PSPDFKit-Popover-Arrow {}`.
- In Server mode, the minimum search query length is now configurable on the server with the environment variable `MIN_SEARCH_QUERY_LENGTH` (default: `3`). This value is passed to the client at load time, and the client will use it to check against the length of the term provided to `NutrientViewer.Instance#search`, `NutrientViewer.Instance#startUISearch`, or the UI search form. If the query to `NutrientViewer.Instance#search` is shorter than this value, the search request will throw an error. To prevent this, it’s recommended to check the minimum query length value from `NutrientViewer.SearchState#minSearchQueryLength` before performing the search. In the case of the UI search form or `NutrientViewer.Instance#startUISearch`, there won’t be an error and the search will just not be performed until the search field value is long enough. In Standalone mode, the default value for this property is `1` and it’s not configurable.

If you use PSPDFKit Server, make sure you read the 2019.3 server migration guide.

For a full list of changes, check out the changelog.

[pspdfkit for web 2019.3]: /blog/pspdfkit-web-2019-3/
[changelog]: /guides/web/changelog/#2019.3
[2019.3 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[web sdk 2019.2 release notes]: /guides/web/release-notes/2019-2/

Explore the key updates in PSPDFKit for Web 2019.3, including annotation changes and migration tips for seamless integration.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2019.2 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2019-2/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2019-2/</guid>
            <pubDate>Fri, 01 Feb 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the API changes and migration steps for PSPDFKit for Web 2019.2, including updates to annotation, bookmark, and form field methods.]]></description>
            <content:encoded><![CDATA[### Notable changes

- We renamed all `*.onPress` events to `*.press` to improve consistency with our event naming schema. The old names are now deprecated and will be removed in a future version. The name changes are as follows:
  - `annotations.onPress` to `annotations.press`
  - `textLine.onPress` to `textLine.press`
  - `page.onPress` to `page.press`
- Shape annotations had their stroke width scaled when resized with the UI. As a result, the different annotations’ stroke widths could vary if resized. This behavior has been changed, so now a shape annotations’ stroke width is kept when resizing.
- The default minimum stamp annotation size, `NutrientViewer.Options.MIN_STAMP_ANNOTATION_SIZE`, has been increased from `10` to `15`. The former value was so small that stamp annotations resized that small would have their text clipped in a way that the stamp text wouldn’t fit (#2977). If your code relies on the former value, you can set it before the first `NutrientViewer.load()` call: `NutrientViewer.Options.MIN_STAMP_ANNOTATION_SIZE = 15`.
- In a recent version, we accidentally disabled an optimization that reduces the number of points an ink annotation creates while drawing. This release restores the previous behavior. You can opt out this behavior by setting `NutrientViewer.Options.INK_EPSILON_RANGE_OPTIMIZATION = 0`.
- We renamed `FormField#annotationPdfObjectIds` to `FormField#annotationIds`.
- When in continuous scroll mode, we now remove custom overlay items from the DOM if you scroll a certain number of pages below the page they items are rendered on. If you previously depended on custom overlay items being persisted in the DOM (e.g. wanted to maintain its state), you will now have to handle this explicitly with the `CustomOverlayItem#onDisappear` method.

  For example, if you’re using a `<video>` tag and want to maintain its current position, you could:

  - Query the current position in `onDisappear` and apply it again with `onAppear`, or
  - Move (`appendChild`) the `<video>` node to another place in the DOM (e.g. an invisible div outside the viewport) and append it back to the custom overlay item `onAppear`. This will keep most of the state around.
- We moved the public CSS classes for shape annotations and ink annotations from their `svg` element to their container (parent).

If you use PSPDFKit Server, make sure you read the 2019.2 server migration guide.

For a full list of changes, check out the changelog.

[pspdfkit for web 2019.2]: /blog/pspdfkit-web-2019-2/
[most of the state]: https://github.com/reactjs/rfcs/pull/34#issuecomment-372493498
[changelog]: /guides/web/changelog/#2019.2
[2019.2 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[web sdk 2019.1 release notes]: /guides/web/release-notes/2019-1/

Learn about the API changes and migration steps for PSPDFKit for Web 2019.2, including updates to annotation, bookmark, and form field methods.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2019.1 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2019-1/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2019-1/</guid>
            <pubDate>Tue, 01 Jan 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore notable improvements in PSPDFKit for Web 2019.1, including font changes and updated annotation models for seamless integration.]]></description>
            <content:encoded><![CDATA[### Notable changes

- We changed the default font families of the viewer to include more system fonts. If you’ve overridden the default font stack, we recommend you check your integration to make sure this change doesn’t overrule yours.
- We added a default padding to the annotation tooltip items. The padding is added to every `ToolItem` except the ones that define a `node` property.
- We added a cloudy border intensity field to polygon, rectangle, and ellipse annotation models.
- We renamed `TextFormField`’s `doNotSpellcheck` field to `doNotSpellCheck`.
- We exposed the default values of annotation models to `NutrientViewer.defaultAnnotationPresets`. Default annotation presets, including variant presets, will now be prefilled with the default values of an annotation type. If you were relying on the default annotation presets being empty at load time, check if you need to update your code to account for this change.
- When creating an ink annotation, any change made to the ink annotation properties will result in a new ink annotation being created. This means that if you are creating an ink annotation using the UI and you change any of its properties — for example, its `color` — then PSPDFKit will store the current annotation and create a new one with only the new properties. This will happen each time a property is changed while creating an ink annotation — even if the settings are changed back to the original — so it can result in the creation of multiple annotations.
- A new default annotation preset variant for ink signature annotations has been added. If you were relying on the preset positions in the `defaultAnnotationPresets` array, check if you need to update your code to account for this change. The new annotation preset ID is named `ink-signature`.

If you use PSPDFKit Server, make sure you read the [2019.1 server migration guide].

For a full list of changes, check out the changelog.

[pspdfkit for web 2019.1]: /blog/pspdfkit-web-2019-1/
[changelog]: /guides/web/changelog/#2019.1
[2019.1 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[web sdk 2018.7 release notes]: /guides/web/release-notes/2018-7/

Explore notable improvements in PSPDFKit for Web 2019.1, including font changes and updated annotation models for seamless integration.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2018.7 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2018-7/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2018-7/</guid>
            <pubDate>Sun, 01 Jul 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about customizable tooltips, enhanced DOM support, and other important features in PSPDFKit for Web 2018.7.]]></description>
            <content:encoded><![CDATA[If you’re maintaining a Server installation, be sure to check out the 2018.7 server migration guide.

### Notable changes

- We upgraded some icons for the color picker part of the annotation toolbar. If you have been relying on element IDs of icons, verify that these IDs still work for you. What we changed:
  - `#ToolbarButton-color` is now `#ToolbarButton-stroke-color`, `#ToolbarButton-fill-color`, or `#ToolbarButton-font-color`, depending on the annotation type
- Toolbar buttons in dropdown items need to be styled with `.PSPDFKit-Input-Dropdown-Item[-state] > .PSPDFKit-Toolbar-Button`.
- We added a `rotation` property to annotations. This change shouldn’t affect current annotations. However, when using Server deployment, some documents might need to be uploaded again if the rotation is off.

For a full list of changes, check out the changelog.

[pspdfkit for web 2018.7]: /blog/pspdfkit-web-2018-7/
[changelog]: /guides/web/changelog/#2018.7
[2018.7 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[web sdk 2018.6 release notes]: /guides/web/release-notes/2018-6/

Learn about customizable tooltips, enhanced DOM support, and other important features in PSPDFKit for Web 2018.7.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2018.6 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2018-6/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2018-6/</guid>
            <pubDate>Fri, 01 Jun 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the latest features in PSPDFKit for Web 2018.6, including stamp annotations and a bookmarks sidebar for improved navigation.]]></description>
            <content:encoded><![CDATA[If you’re maintaining a Server installation, be sure to check out the 2018.6 server migration guide.

### Notable changes

- Adds two toolbar items to `NutrientViewer.defaultToolbarItems`:
  - `sidebar-bookmarks` for the bookmarks sidebar. It is part of the `sidebar` `dropdownGroup`.
  - `stamp` for stamp annotations.
- The `stamp` and `image` toolbar items are now grouped in a `dropdownGroup` called `image`.
- `dropdownGroup`s with only one item are now rendered as flat buttons instead of dropdowns.
- Prior to this release, custom toolbar item icons with data URIs appeared shifted to the left. This is now fixed, and previous workarounds to this issue are no longer needed. But just in case you need additional CSS rules to style custom toolbar icons, you can use the `.PSPDFKit-Toolbar-Button-Icon` CSS selector.
- API: Changes annotation APIs to not throw synchronously but rather reject with an error instead.

For a full list of changes, check out the changelog.

[pspdfkit for web 2018.6]: /blog/pspdfkit-web-2018-6/
[changelog]: /guides/web/changelog/#2018.6
[defaulttoolbaritems]: /api/web/variables/NutrientViewer.defaultToolbarItems.html
[2018.6 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[web sdk 2018.5 release notes]: /guides/web/release-notes/2018-5/

Learn about the latest features in PSPDFKit for Web 2018.6, including stamp annotations and a bookmarks sidebar for improved navigation.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2018.5 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2018-5/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2018-5/</guid>
            <pubDate>Tue, 01 May 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the latest updates in PSPDFKit 2018.5, featuring image annotations and enhanced annotation tools for PDFs.]]></description>
            <content:encoded><![CDATA[If you’re maintaining a Server installation, be sure to check out the 2018.5 server migration guide.

### API changes

- Adds `Configuration#enableServiceWorkerSupport` to not bypass service workers when loading stylesheets inside PSPDFKit for Web.
- Adds `defaultAnnotationPresets` for annotation presets. You can read more about customizing annotation presets in our Customizing the Toolbar guide.
- Removes `InteractionMode.LAYOUT_CONFIGURATION`. The state of the layout configurator will be no longer be exposed.

### Notable changes

- The order of `defaultToolbarItems` was changed.
- New toolbar items for document outline, document annotation sidebar, the `highlighter` variant, and the `arrow` variant were added to the `defaultToolbarItems`.
- We fixed an issue with exported and imported XFDF files on rotated pages.
- The placement logic of dropdowns has changed, and CSS rules that rely on the HTML structure of the dropdowns might need to be updated.

For a full list of changes, check out the changelog.

[pspdfkit for web 2018.5]: /blog/pspdfkit-web-2018-5/
[changelog]: /guides/web/changelog/#2018.5
[cover endpoint]: /guides/web/server-backed/document-api/#load-a-cover-photo-of-a-document-65facf
[`defaulttoolbaritems`]: /api/web/variables/NutrientViewer.defaultToolbarItems.html
[`defaultannotationpresets`]: /api/web/variables/NutrientViewer.defaultAnnotationPresets.html
[2018.5 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[customizing the toolbar]: /guides/web/customizing-the-interface/customizing-the-toolbar/#annotation-variant-buttons
[web sdk 2018.4 release notes]: /guides/web/release-notes/2018-4/

Learn about the latest updates in PSPDFKit 2018.5, featuring image annotations and enhanced annotation tools for PDFs.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2018.4 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2018-4/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2018-4/</guid>
            <pubDate>Sun, 01 Apr 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover key enhancements in PSPDFKit for Web 2018.4, including shape annotations and API updates for better document management.]]></description>
            <content:encoded><![CDATA[If you’re maintaining a Server installation, be sure to check out the 2018.4 server migration guide.

### API changes

- This version removes the `Instance#renderCover` API method in favor of `Instance#renderPageAsArrayBuffer`. We deprecated this API in PSPDFKit 2018.2.

### Notable changes

- All covers will now contain annotations as well.
- The following classes are now used for dropdowns instead of sliders:
  - `.PSPDFKit-Ink-Annotation-Toolbar-Opacity`
  - `.PSPDFKit-Ink-Annotation-Toolbar-Line-Width`
  - `.PSPDFKit-Text-Annotation-Toolbar-Opacity`
  - `.PSPDFKit-Text-Markup-Annotation-Toolbar-Opacity`
- The `.ColorSet` class was replaced by `.PSPDFKit-Input-Color-Dropdown`.
  The color dropdowns are now separated into foreground and background color for each annotation.
  The combinations for the annotations are:
  - Text: `.PSPDFKit-Text-Annotation-Toolbar-Font-Color` / `.PSPDFKit-Text-Annotation-Toolbar-Background-Color`
  - Ink: `.PSPDFKit-Ink-Annotation-Toolbar-Stroke-Color` / `.PSPDFKit-Ink-Annotation-Toolbar-Background-Color`
- The order of `defaultToolbarItems` was changed.
- A new toolbar item for shape annotations was added to the `defaultToolbarItems`.
- We fixed an issue with PDFs that didn’t have permissions to modify annotations and forms. These PDFs did not render any forms before.

For a full list of changes, check out the changelog.

[pspdfkit for web 2018.4]: /blog/pspdfkit-web-2018-4/
[changelog]: /guides/web/changelog/#2018.4
[cover endpoint]: /api/reference/document-engine/client/#tag/Documents/operation/render-cover
[`defaulttoolbaritems`]: /api/web/variables/NutrientViewer.defaultToolbarItems.html
[2018.4 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[2018.2 web migration guide]: /guides/web/migration-guides/2018-2-migration-guide/#render-bitmaps-732135
[`instance#renderpageasarraybuffer`]: /api/web/classes/NutrientViewer.Instance.html#renderpageasarraybuffer
[web sdk 2018.3 release notes]: /guides/web/release-notes/2018-3/

Discover key enhancements in PSPDFKit for Web 2018.4, including shape annotations and API updates for better document management.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2018.3 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2018-3/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2018-3/</guid>
            <pubDate>Thu, 01 Mar 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the latest updates in PSPDFKit for Web 2018.3, including ink signatures, password protection, and a simplified deployment structure.]]></description>
            <content:encoded><![CDATA[If you’re maintaining a Server installation, make sure to check out the 2018.3 server migration guide.

### Updated package structure

In this release, we introduce a new and simpler package structure. This might require changes on your end if you’re using our standalone deployment option.

With the exception of the main `pspdfkit.js` bundle, all of the library files are now located in the `pspdfkit-lib` subfolder. This new structure makes it easier to copy PSPDFKit’s artifacts and allows us to introduce new ones over time without requiring you to update your setup.

Before, it was necessary to copy the individual files like so:

```sh
cp ./node_modules/pspdfkit/dist/pspdfkit.css \
  ./node_modules/pspdfkit/dist/pspdfkit.wasm \
  ./node_modules/pspdfkit/dist/pspdfkit.wasm.js \
  ./node_modules/pspdfkit/dist/pspdfkit.asm.js \
  ./node_modules/pspdfkit/dist/pspdfkit.asm.js.mem \
  ./dist
```

You could also have done this via a build tool.

Beginning with PSPDFKit for Web 2018.3, all you need to do is copy a single folder:

```sh
cp -R ./node_modules/pspdfkit/dist/pspdfkit-lib dist
```

Our guides and example applications were updated to reflect this change.

### Annotation events

One important bug fix of this release changes the `annotations.create` event. This event previously fired when loading annotations in _some_ cases. These cases are:

- When using a server-backed deployment with `instant` set to `false`.
- When using a standalone deployment.

If your code was relying on this behavior, you will need to listen for the newly added `annotations.load` event. This will now fire in any case where annotations are loaded from the document. This might happen once for all annotations, or it might be scoped to the pages in the viewport.

### Connecting self-hosted assets with PSPDFKit Server

If you previously used the server-backed flavor of PSPDFKit and hosted the JavaScript files on your own server, you had to use the `baseUrl` option to tell PSPDFKit to connect to the correct server. Since this option was also used as the load path for other JavaScript resources, we’ve created a dedicated option to connect PSPDFKit Server — the `serverUrl`:

```diff
NutrientViewer.load({
-  baseUrl: "https://example.com",
+  serverUrl: "https://example.com",
});
```

For a full list of changes, check out the changelog.

[pspdfkit for web 2018.3]: /blog/pspdfkit-web-2018-3/
[changelog]: /guides/web/changelog/#2018.3
[`annotations.load`]: /api/web/types/Events.AnnotationsLoadEvent.html
[2018.3 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[`baseurl`]: /api/web/interfaces/Configuration.html#baseurl
[`serverurl`]: /api/web/interfaces/Configuration.html#serverurl
[web sdk 2018.2 release notes]: /guides/web/release-notes/2018-2/

Learn about the latest updates in PSPDFKit for Web 2018.3, including ink signatures, password protection, and a simplified deployment structure.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2018.2 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2018-2/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2018-2/</guid>
            <pubDate>Thu, 01 Feb 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the features of PSPDFKit for Web 2018.2 including Electron support and API updates.]]></description>
            <content:encoded><![CDATA[If you’re maintaining a Server installation, make sure to check out the 2018.2 server migration guide.

### Render bitmaps

This version deprecates the `Instance#renderCover` API method in favor of `Instance#renderPageAsArrayBuffer`, which now works on server deployments too.

In contrast to `renderCover`, the new method expects a mandatory `pageIndex` as its second argument.

To migrate, replace any occurrence of `renderCover` with `Instance#renderPageAsArrayBuffer`, and make sure to pass `0` as the `pageIndex` in the place where you were previously omitting the second argument:

{% tabs variant="underline-accent" %}
{% tabitem label="ES6+" %}
```js
const buffer = await instance.renderCover({ width: 400 });
// becomes
const buffer = await instance.renderPageAsArrayBuffer({ width: 400 }, 0);
```
{% /tabitem %}

{% tabitem label="JAVASCRIPT" %}
```js
instance.renderCover({ width: 400 }).then(function(buffer) {
  console.log(buffer);
});
// becomes
instance.renderPageAsArrayBuffer({ width: 400 }, 0).then(function(buffer) {
  console.log(buffer);
});
```
{% /tabitem %}
{% /tabs %}

{% tabs variant="underline-accent" %}
{% tabitem label="ES6+" %}
```js
const buffer = await instance.renderCover({ width: 400 }, 2);
// becomes
const buffer = await instance.renderPageAsArrayBuffer({ width: 400 }, 2);
```
{% /tabitem %}

{% tabitem label="JAVASCRIPT" %}
```js
instance.renderCover({ width: 400 }, 2).then(function(buffer) {
  console.log(buffer);
});
// becomes
instance.renderPageAsArrayBuffer({ width: 400 }, 2).then(function(buffer) {
  console.log(buffer);
});
```
{% /tabitem %}
{% /tabs %}

PSPDFKit for Web 2018.2 also introduces `Instance#renderPageAsImageURL`, which renders a page and returns a URL to the generated image. This method works on standalone and server-based deployments.

For a full list of changes, check out the changelog.

[pspdfkit for web 2018.2]: /blog/pspdfkit-web-2018-2/
[`instance#rendercover`]: /api/web/classes/NutrientViewer.Instance.html#rendercover
[`instance#renderpageasarraybuffer`]: /api/web/classes/NutrientViewer.Instance.html#renderpageasarraybuffer
[`instance#renderpageasimageurl`]: /api/web/classes/NutrientViewer.Instance.html#renderpageasimageurl
[2018.2 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[changelog]: /guides/web/changelog/#2018.2
[web sdk 2018.1 release notes]: /guides/web/release-notes/2018-1/

Explore the features of PSPDFKit for Web 2018.2 including Electron support and API updates.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2018.1 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2018-1/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2018-1/</guid>
            <pubDate>Mon, 01 Jan 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the enhancements in PSPDFKit 2018.1, including new toolbar items, XFDF support, and improved WebAssembly initialization.]]></description>
            <content:encoded><![CDATA[If you’re maintaining a Server installation, make sure to check out the 2018.1 server migration guide.

### Notable changes

- A new toolbar item was added to the `defaultToolbarItems` to show/hide the thumbnail sidebar, `sidebar-thumbnails`. When it is clicked, it will update the `ViewState`.
- The `ViewState` has new properties:
  - `ViewState#sidebarMode` to toggle the visibility of the sidebar.
  - `ViewState#pagesRotation` to control the rotation of all pages. The value must be a multiple of 90 degrees. The helper methods `ViewState#rotateLeft()` and `ViewState#rotateLeft()` were added to quickly rotate by 90 degrees in one direction.
- The existing `Instance#exportInstantJSON()` API is now also available on server deployments.
- A new API was added to export XFDF: `Instance#exportXFDF()`.
- A new, standalone-exclusive API was added to import XFDF when loading a PDF (`Configuration#XFDF` and `Configuration#XFDFKeepCurrentAnnotations`). For server setups, this is part of the Server API.
- When loading a WebAssembly instance, support for IndexedDB caching and streaming instantiation will now be detected. If the browser supports any of these techniques, we’ll use it to improve WebAssembly initialization time.
- The new WebAssembly streaming instantiation will require a specific MIME type for the `pspdfkit.wasm` artifact. This needs to be configured by your web server if you’re not using PSPDFKit Server. Make sure that the response header for the WebAssembly request returns `Content-Type=application/wasm`.

For a full list of changes, check out the changelog.

[pspdfkit for web 2018.1]: /blog/pspdfkit-web-2018-1/
[2018.1 server migration guide]: /guides/product-archives-and-deprecated-solutions/
[changelog]: /guides/web/changelog/#2018.1
[`defaulttoolbaritems`]: /api/web/variables/NutrientViewer.defaultToolbarItems.html
[`viewstate#sidebarmode`]: /api/web/classes/NutrientViewer.ViewState.html#sidebarmode
[`viewstate#pagesrotation`]: /api/web/classes/NutrientViewer.ViewState.html#pagesrotation
[`instance#exportinstantjson()`]: /api/web/classes/NutrientViewer.Instance.html#exportinstantjson
[`instance#exportxfdf()`]: /api/web/classes/NutrientViewer.Instance.html#exportxfdf
[xfdf import server]: /guides/product-archives-and-deprecated-solutions/
[`configuration#xfdf`]: /api/web/interfaces/Configuration.html#xfdf
[`configuration#xfdfkeepcurrentannotations`]: /api/web/interfaces/Configuration.html#xfdfkeepcurrentannotations
[streaming instantiation]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming
[indexeddb caching]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
[web sdk 2017.9 release notes]: /guides/web/release-notes/2017-9/
[`viewstate`]: /api/web/classes/NutrientViewer.ViewState.html

Explore the enhancements in PSPDFKit 2018.1, including new toolbar items, XFDF support, and improved WebAssembly initialization.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2017.9 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2017-9/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2017-9/</guid>
            <pubDate>Fri, 01 Sep 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the new form support, responsive toolbar, and headless mode in PSPDFKit for Web 2017.9. Check migration and annotation guides for details!]]></description>
            <content:encoded><![CDATA[If you’re maintaining a Server installation, make sure to check out the server migration guides.

### Notable changes

- All annotation APIs will now also return `WidgetAnnotation`s. This special type of annotation is required to render form widgets in a PDF and cannot be modified. Calling any of the modifying APIs (create, update, or delete) will cause an error when a `WidgetAnnotation` is used.
- A comprehensive guide for forms in PDFs can be found in our form guides.
- A new default toolbar item was added: `annotate`. This item will show the annotation button on small screens. To remove one specific annotation tool, it’s still sufficient to remove the individual type from the toolbar items list. An example can be found in our toolbar customization guide.
- Since migrating `Instance#destroy()` in 2017.7, the method is now no longer available. Refer to the 2017.7 migration guide for information on how to upgrade.

For a full list of changes, check out the changelog.

[pspdfkit for web 2017.9]: /blog/pspdfkit-web-2017-9/
[form guides]: ../../forms/introduction-to-forms/
[`widgetannotation`]: /api/web/classes/NutrientViewer.Annotations.WidgetAnnotation.html
[annotation guides]: ../../annotations/introduction-to-annotations/
[server migration guides]: /guides/product-archives-and-deprecated-solutions/
[changelog]: /guides/web/changelog/#2017.9
[toolbar customization guide]: ../../customizing-the-interface/customizing-the-toolbar/
[web sdk 2017.8 release notes]: /guides/web/release-notes/2017-8/
[2017.7 migration guide]: /guides/web/release-notes/2017-7/

Learn about the new form support, responsive toolbar, and headless mode in PSPDFKit for Web 2017.9. Check migration and annotation guides for details!]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2017.8 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2017-8/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2017-8/</guid>
            <pubDate>Tue, 01 Aug 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn to seamlessly upgrade annotation IDs in PSPDFKit Web 2017.8 with our comprehensive migration guide.]]></description>
            <content:encoded><![CDATA[This requires that all clients (iOS, Android, and Web), along with the server, are updated to the latest version at the same time. If you’re maintaining an Instant setup, make sure to check out the server migration guides.

### Annotation API changes

- All `Annotation` subclasses now have a string value for the `id` field. This ID will still be generated automatically whenever `Instance#createAnnotation` is called.
- The concept of local ID and global ID is gone completely. The Web client can now generate a unique string ID, which is also used to reference the annotation when it is saved to Instant or Instant JSON.
- `Instance#resolveLocalId` was removed and is now available as `Instance#ensureAnnotationSaved`. This method still accepts an annotation and will resolve the promise when the annotation is persisted. The `id` property of the annotation will now stay stable and will no longer be updated when the promise resolves.
- The document format of Instant JSON no longer requires the `lastAnnotationId` property. Importing the previous version of Instant JSON (with number values for annotation IDs) using the [`Config#instantJSON`] option is still supported. When [`Instance#exportInstantJSON`] is called the next time, the format will automatically be upgraded. The IDs of existing annotations will simply be cast to string (so `-1` will become `"-1"`).

For more details, check out our updated annotation and [Instant JSON] guides.

For a full list of changes, check out the changelog.

[`id`]: /api/web/classes/NutrientViewer.Annotations.Annotation.html#id
[`instance#createannotation`]: /api/web/classes/NutrientViewer.Instance.html#createannotation
[`annotation`]: /api/web/classes/NutrientViewer.Annotations.Annotation.html
[`instance#ensureannotationsaved`]: /api/web/classes/NutrientViewer.Instance.html#ensurechangessaved
[instant json]: ../../importing-exporting/instant-json/
[`config#instantjson`]: /api/web/interfaces/Configuration.html#instantjson
[`instance#exportinstantjson`]: /api/web/classes/NutrientViewer.Instance.html#exportinstantjson
[annotation guides]: ../../annotations/introduction-to-annotations/
[server migration guides]: /guides/product-archives-and-deprecated-solutions/
[changelog]: /guides/web/changelog/#2017.8
[web sdk 2017.7 release notes]: /guides/web/release-notes/2017-7/

Learn to seamlessly upgrade annotation IDs in PSPDFKit Web 2017.8 with our comprehensive migration guide.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2017.7 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2017-7/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2017-7/</guid>
            <pubDate>Sat, 01 Jul 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore the new features of PSPDFKit for Web 2017.7, including API changes and improved printing capabilities.]]></description>
            <content:encoded><![CDATA[This release requires changes to the server as well. Check out our server migration guides to learn more.

Explore the new features of PSPDFKit for Web 2017.7, including API changes and improved printing capabilities.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2017.6 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2017-6/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2017-6/</guid>
            <pubDate>Thu, 01 Jun 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover the new features in PSPDFKit 2017.6, including note annotations, improved zoom modes, and real-time collaboration for seamless document editing.]]></description>
            <content:encoded><![CDATA[- `ViewState#viewMode` is deprecated in favor of the newly added `ViewState#viewMode` and `ViewState#scrollMode` options, and will be removed in version 2017.7.
- `ViewState#pageSpacing` is now used to determine the spacing between pages when in double-page mode. The default value has therefore been changed to zero. For the previous behavior, use `ViewState#spreadSpacing` instead.
- Zoom modes have been renamed to better reflect their behavior in regard to spreads. The deprecated options will be removed in version 2017.7.
  - Instead of `ZoomMode.PAGE_FIT`, use `ZoomMode.FIT_TO_VIEWPORT`.
  - Instead of `ZoomMode.PAGE_WIDTH`, use `ZoomMode.FIT_TO_WIDTH`.

With this release, we also added support for deleting imported documents from PSPDFKit Server’s database. See our API documentation for further information.

For a full list of changes, check out the changelog.

[pspdfkit for web 2017.6]: /blog/pspdfkit-web-2017-6/
[api documentation]: /guides/product-archives-and-deprecated-solutions/
[changelog]: /guides/web/changelog/#2017.6
[web sdk 2017.3 release notes]: /guides/web/release-notes/2017-3/
[`viewstate#viewmode`]: /api/web/classes/NutrientViewer.ViewState.html#viewmode
[`viewstate#scrollmode`]: /api/web/classes/NutrientViewer.ViewState.html#scrollmode
[`viewstate#pagespacing`]: /api/web/classes/NutrientViewer.ViewState.html#pagespacing
[`viewstate#spreadspacing`]: /api/web/classes/NutrientViewer.ViewState.html#spreadspacing
[`zoommode.page_fit`]: /api/web/enums/NutrientViewer.ZoomMode.html
[`zoommode.fit_to_viewport`]: /api/web/enums/NutrientViewer.ZoomMode.html
[`zoommode.page_width`]: /api/web/enums/NutrientViewer.ZoomMode.html
[`zoommode.fit_to_width`]: /api/web/enums/NutrientViewer.ZoomMode.html

Discover the new features in PSPDFKit 2017.6, including note annotations, improved zoom modes, and real-time collaboration for seamless document editing.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[2017.3 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/2017-3/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/2017-3/</guid>
            <pubDate>Wed, 01 Mar 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[Latest updates and release notes for Nutrient Web SDK, including new features, improvements, and bug fixes.]]></description>
            <content:encoded><![CDATA[However, we noticed an issue that would come up repeatedly in support requests: Customers don’t want to have to mirror their access control to PSPDFKit Server, preferring to rely on signed JSON Web Tokens (JWTs) instead. That’s why we’re officially deprecating this functionality.

To do this, we updated the JWT payload format and removed the option to authenticate using a `"user_id"`. The related backend APIs for assigning users to documents have been removed as well — namely `/api/change_users` and `/api/set_users`.

If you were relying on user IDs to authenticate your documents, you will need to update the JWT payload to a finer-grained `"permissions"` list. For example, this:

```json
{
  "document_id": "abc",
  "user_id": "test_user"
}
```

becomes this:

```json
{
  "document_id": "abc",
  "permissions": ["read-document", "edit-annotations"]
}
```

Read on to find out more about the newly introduced concept of permissions.

Latest updates and release notes for Nutrient Web SDK, including new features, improvements, and bug fixes.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.22 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-22/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-22/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.22]]></description>
            <content:encoded><![CDATA[### The blocks UI customization API is removed

The blocks API deprecated in 1.20 is gone. The `ui` slot configuration is now the only supported way to customize the viewer’s UI. **If you still customize through blocks, your customization no longer applies and the viewer renders its default UI.**

`ui._blocks` and root-level block keys are ignored, and each one logs a `console.error` naming the key it ignored. Loading isn’t blocked — a stale configuration still opens the document:

```js
// Removed: block-based customization. Logged and ignored.
NutrientViewer.load({
  ui: {
    _blocks: {
      [NutrientViewer.Interfaces.Search]: ({ props }) => ({
        content: myCustomSearch(props),
      }),
    },
  },
});

// Use the equivalent slot instead.
NutrientViewer.load({
  ui: {
    search: (getInstance, id) => ({
      render: () => myCustomSearch(),
    }),
  },
});
```

Four exports were part of that API and now throw a migration error when accessed, rather than being `undefined`: `NutrientViewer.UI.createBlock`, `NutrientViewer.UI.Recipes`, `NutrientViewer.UI.Decorators`, and `NutrientViewer.UI.Interfaces`.

The rendered DOM is unchanged — every `data-block-id` attribute is preserved — so visual tests and selectors that target them keep working. For the list of slots and what each one replaces, refer to the UI customization and supported slots guides.

### Deprecated collection methods

The SDK’s collection types inherit Immutable’s full method surface, most of which the SDK has never supported. Nineteen of those methods are now marked deprecated in the published type declarations and the API reference, each naming the supported replacement. **No method was removed and every call keeps working**, but the editor now flags them before you build on something that can’t be kept.

| Method         | Replacement                                                                         |
| -------------- | ----------------------------------------------------------------------------------- |
| `asImmutable`  | Build the value once, or use `withMutations()`.                                     |
| `asMutable`    | Use `withMutations()`.                                                              |
| `cacheResult`  | Drop the call — the collections the SDK exposes are already eager.                  |
| `entrySeq`     | Use `entries()`.                                                                    |
| `filterNot`    | Use `filter()` with the predicate negated.                                          |
| `findEntry`    | Use `entries()`, taking the entry you need.                                         |
| `findKey`      | Loop over `entries()`.                                                              |
| `flatten`      | Use `flatMap()`.                                                                    |
| `fromEntrySeq` | Use `Map(entries)`.                                                                 |
| `hasIn`        | Use `get()` followed by `has()`.                                                    |
| `mergeIn`      | Use `update()` followed by `merge()`.                                               |
| `removeIn`     | Use `deleteIn()`, or `update()` followed by `delete()`.                             |
| `setSize`      | Construct the collection with the values it should hold.                            |
| `toIndexedSeq` | Use `values()`.                                                                     |
| `toKeyedSeq`   | Use `entries()`.                                                                    |
| `toMap`        | Use `Map(entries())`.                                                               |
| `toSeq`        | Use `entries()` on a keyed collection, or `values()` on an indexed or set-like one. |
| `toSetSeq`     | Use `values()`.                                                                     |
| `wasAltered`   | Compare the collections with `equals()`.                                            |

### Compound measurements

Measurement labels can show a mixed-unit value — “6 ft 3 in” instead of “6.25 ft” — matching the format Acrobat and Bluebeam Revu author. Compound units are configured per scale, as an ordered list of progressively smaller units, each with its own precision, appended to the scale’s primary unit:

```js
NutrientViewer.load({
  measurementValueConfiguration: (documentScales) => [
    {
      name: "Feet & Inches",
      scale: {
        unitFrom: NutrientViewer.MeasurementScaleUnitFrom.INCHES,
        unitTo: NutrientViewer.MeasurementScaleUnitTo.FEET,
        fromValue: 1,
        toValue: 3
      },
      precision: NutrientViewer.MeasurementPrecision.TWO,
      compoundUnits: [
        {
          unitTo: NutrientViewer.MeasurementScaleUnitTo.INCHES,
          precision: NutrientViewer.MeasurementPrecision.WHOLE
        }
      ],
      selected: true
    },
    ...documentScales
  ]
});
```

The chain is generic across measurement systems — `ft → in`, `m → cm → mm`, `yd → ft → in` — and each annotation renders from its own scale, so a metric scale can’t pick up an imperial sub-unit. A configured sub-unit that isn’t strictly smaller than the scale’s unit falls back to a single-unit label, as do area measurements.

The chain is persisted on the annotation as a multi-entry `/Measure /D` number-format array, so it survives save, reload, and export, and compound measurements authored elsewhere are read back correctly. `instance.setMeasurementScale(scale, { compoundUnits, name })` writes the scale and its chain into the document, so the scale is offered again after reopening without re-supplying `measurementValueConfiguration`.

Compound measurements are standalone mode only. Document Engine ignores the compound chain. For more information, refer to the measurements guide.

### Per-page initial render callback

`onInitialPageRender` is called once per page, the first time that page renders, which makes time to first rendered page directly measurable instead of something you infer from timers or mutation observers:

```js
const startedAt = performance.now();
let reported = false;

NutrientViewer.load({
  onInitialPageRender: function ({ pageIndex }) {
    if (reported) return;

    reported = true;
    console.log(`page ${pageIndex} rendered after ${performance.now() - startedAt}ms`);
  },
  // ...
});
```

The callback fires only on a successful render, so the page already has content drawn when you’re called. It never fires twice for the same page index — zoom, rotation, resize, and scrolling back to a page don’t re-trigger it — and the first call can arrive before `load()` resolves. Pages next to the current one are pre-rendered, so a page can be reported slightly before the reader scrolls to it. The `OnInitialPageRenderCallback` and `InitialPageRenderInfo` types ship in the public declarations.

### Typed message IDs and locale tags

Localization is now typed. Every message ID the SDK ships and every locale it provides a catalog for is suggested as you type, and the types admit that a locale you haven’t loaded yet isn’t there:

```ts
NutrientViewer.I18n.messages.en = { print: "Print document" };

await NutrientViewer.I18n.preloadLocalizationData("de");
NutrientViewer.I18n.messages.de!.print = "Dokument drucken";

await instance.setLocale("de");
```

`locale`, `setLocale()`, `preloadLocalizationData()`, and `loadTextComparison()` autocomplete the shipped locale tags while still accepting a custom tag you push onto `NutrientViewer.I18n.locales`. The `Locale`, `MessageId`, `LocaleMessages`, and `LocaleMessageOverrides` types are part of the public API.

**This is a type-only tightening**: the locale keys of `NutrientViewer.I18n.messages` are now optional, so reading `NutrientViewer.I18n.messages.de.print` no longer compiles. Add a guard, or a non-null assertion after preloading. Runtime behavior is unchanged, and JavaScript integrations are unaffected. For the full list of message IDs, refer to the localization guide in the API reference.

### `setFocus()` in PDF JavaScript

Form fields support the `setFocus()` PDF JavaScript method, so a document script can move the cursor into a named field:

```js
this.getField("total").value = "0";
this.getField("total").setFocus();
```

The call previously threw, which discarded the rest of the script — including assignments it had already made. A field on another page is scrolled into view rather than only scrolled to the top of its page.

### Immediate saving for DWS Viewer API sessions

A DWS Viewer API session loaded with `NutrientViewer.load({ container, session })` runs Instant, but was using the save mode meant for Instant being off. It now uses `AutoSaveMode.IMMEDIATE`, the mode Instant implies. **Edits are sent as they’re made instead of being batched to the next flush point**, `hasUnsavedChanges()` reports accurately, and applying redactions completes instead of hanging indefinitely. Passing `instant: false` or an explicit `autoSaveMode` is unaffected.

### Other additions

- `NutrientViewer.Error` ships type declarations instead of being typed as `any`.
- The `inlineWorkers` configuration option moved from `StandaloneConfiguration` to `SharedConfiguration`, so server-backed deployments can opt out of inline workers as well.
- Importing Instant JSON that contains many form field values on JavaScript-backed forms is faster: the document’s calculations run once for the whole import instead of once per value.
- GdPicture is updated to 14.4.8.1. Refer to the GdPicture changelog for details.
- The GdPicture WASM components are listed in the Web SDK SBOM.
- The internal static `defaultValues` property is no longer part of the published type declarations.

### Rendering

- Fixes annotation and form field text being dropped when it contains symbols such as ★ (U+2605) that were erroneously classified as emojis.
- Fixes emoji missing from annotation text when using dynamically loaded fonts.
- Fixes incorrect font styles for diacritic characters in PDFs that use configured font substitutions.
- Fixes applying a redaction removing unrelated text on the same page in more cases, including text drawn by a form XObject, an annotation appearance, a soft mask, or a Type 3 glyph.
- Fixes applying a redaction removing unrelated text on the same page when that text is drawn with the `'` or `"` operators.

### Forms and document editing

- Fixes a PDF JavaScript call to `checkThisBox` being ignored on a read-only checkbox or radio button.
- Fixes a text form field showing its previously typed value again when refocused after a PDF JavaScript action changed it.
- Fixes calculated form fields keeping a stale value, and reporting a self-modification error, when their stored values are imported through Instant JSON or XFDF.
- Fixes a crash when processing or exporting large documents whose forms use a calculation order.
- Fixes copied form fields not being fillable on the pages where they appear in some documents.
- Fixes form field text rendering as unrelated symbols when the requested font is missing from the document.
- Fixes symbols like checkmarks being replaced by fallback glyphs in exported and flattened form field appearances when dynamic fonts are enabled.
- Fixes `WidgetAnnotation#isBold` and `isItalic` deserializing as `null` instead of the documented `false` default when the document specifies no font style.
- Fixes non-image payloads being embedded into populated Office document templates. Payloads without a supported image signature, or whose explicit format conflicts with detected image data, are now rejected.

### User interface and accessibility

- Fixes Command/Control-drag failing to create an annotation selection rectangle on pages after the first.
- Fixes a font size, font family, text color, or background color change applied to a plain text annotation with `instance.update()` not appearing in the open inline editor until the editing session ends.
- Fixes an error shown in the sidebar when `ViewState#sidebarOptions` omits the entry for that sidebar.
- Fixes an uncatchable “Content editing not initialized” promise rejection when the content editor is used while a content editing session is being saved.
- Fixes annotation tools becoming usable when read-only mode is disabled on a license without annotation editing.
- Fixes misaligned comments and clipped comment edit fields when a custom `CommentAvatar` renderer is used.
- Fixes content editor errors omitting the underlying cause from their message.
- Fixes unrelated errors being reported as an invalid theme with their original message rewritten.

### Loading, platform, and API reference

- Fixes scrolling through text-heavy documents temporarily blocking interaction with the viewer and the embedding application, by moving synthetic text-selection font serialization to a dedicated worker. Deployments with a strict Content Security Policy should review the `inlineWorkers` configuration option.
- Fixes broken links and missing type descriptions in the API reference.
- Fixes the API reference showing an internal type for the `instant` configuration option.
- Fixes the API reference showing rest parameters as a single array argument instead of `...name`.
- Fixes the `getBlocks` API reference claiming it reads all blocks, and documents that a page reads empty until its text is detected.
- Fixes the documented return value of `setDocumentComparisonMode()`, which described only one of the three outcomes the returned promise can represent.

For a full list of fixes, refer to the changelog.

{% alert line="multi-line" %}
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. Compound measurements are standalone mode only and are ignored by Document Engine. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.21 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.22.0
[web sdk 1.21 release notes]: /guides/web/release-notes/1-21/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[ui-customization]: /guides/web/user-interface/ui-customization/introduction/
[supported-slots]: /guides/web/user-interface/ui-customization/supported-slots/
[measurements]: /guides/web/measurements/configure-measurements/
[localization-api]: /api/web/documents/Localization.html
[csp]: /guides/web/troubleshooting/content-security-policy/
[gdpicture-changelog]: /guides/dotnet/changelog/#14.4.8.1

Lists important changes for Nutrient Web SDK 1.22]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.21 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-21/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-21/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.21]]></description>
            <content:encoded><![CDATA[### 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 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 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 shaded boxes appearing over artwork when rendering PDFs with DeviceN black gradients in CMYK transparency groups.
- 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.

{% alert line="multi-line" %}
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.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.20 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.21.0
[web sdk 1.20 release notes]: /guides/web/release-notes/1-20/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[localization-api]: /api/web/documents/Localization.html

Lists important changes for Nutrient Web SDK 1.21]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.20 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-20/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-20/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.20]]></description>
            <content:encoded><![CDATA[### The blocks UI customization API is deprecated

The `ui._blocks` customization API is deprecated and will be removed in a future release. Use the `ui` slot configuration instead. **If you customize the UI through blocks, migrate to the equivalent slot.**

```js
// Deprecated: block-based customization.
NutrientViewer.load({
  ui: {
    _blocks: {
      [NutrientViewer.Interfaces.Search]: ({ props }) => ({
        content: myCustomSearch(props),
      }),
    },
  },
});

// Use the equivalent slot instead.
NutrientViewer.load({
  ui: {
    search: (getInstance, id) => ({
      render: () => myCustomSearch(),
    }),
  },
});
```

Because `_blocks` isn’t part of the published type declarations, the console is the only channel available for this notice. Loading a configuration that uses it now logs one deprecation warning:

- Configuring the same component through both APIs logs an additional warning per component, naming the slot path and the block so you know exactly what to migrate. Which of the two renders depends on the component and on what the slot provides, so this case was previously invisible. The `minimal` UI preset hides every slot a block maps onto, so conflicts surface there too.
- Passing `_blocks` to `instance.setUI()` has never had an effect — the value is always overwritten with the current one — and now reports that instead of failing silently.

For the list of slots and what each one replaces, refer to the UI customization and supported slots guides.

### Default parameter values in PDF JavaScript

PDF JavaScript function declarations now support default parameter values, so documents whose scripts rely on them evaluate correctly instead of failing to parse:

```js
function formatTotal(amount, currency = "USD") {
  return amount + " " + currency;
}
```

For more information, refer to the JavaScript support guide.

### Stricter validation for models, toolbars, and tool items

Model, toolbar, and tool item validation now runs on shared schemas rather than hand-written checks, which closes a set of holes where malformed input was accepted or surfaced as an opaque `TypeError`. **Input that was previously tolerated now throws**, so review any call site that passes values built from user input or an external source.

- Non-finite numbers (`NaN`, `Infinity`, `-Infinity`) are rejected where a number is expected — for example, `Bookmark.sortKey` and `CustomOverlayItem.pageIndex`.
- Malformed comments, mentionable users, and document descriptors report a named validation error. For example, `new NutrientViewer.DocumentDescriptor(null)` now throws `DocumentDescriptor: Expected an object.` instead of `TypeError: Cannot destructure property 'filePath' of 'null'`.
- `instance.setMentionableUsers()` stored its argument unchecked and now applies the same rules as the `load()` configuration path.
- `avatarUrl` and `description` on mentionable users are checked whenever they’re present, not only when they’re truthy, so values such as `0` and `false` are no longer accepted.
- Toolbar items, tool items, Document Editor footer items, and inline text selection toolbar items reject invalid `string` and `mediaQueries` values consistently across all variants.
- DOM nodes in tool items are validated by node type rather than with `instanceof Node`, so a node created in another realm — an iframe, for example — is accepted.

For any given invalid input, the field reported first is unchanged, so error strings you match on in existing code stay the same.

### Read-only geometry model types

The geometry models — `Rect`, `Point`, `Size`, `Inset`, `DrawingPoint`, and `TransformationMatrix` — now expose read-only properties and the same standard Immutable Record method subset as every other model. This is a type-only change: Runtime behavior is untouched, and these objects were already immutable. **TypeScript now reports an error where your code assigns to a property**; use `set()` to derive a new value instead:

```js
const rect = new NutrientViewer.Geometry.Rect({
  left: 0,
  top: 0,
  width: 100,
  height: 50,
});

// Previously allowed by the types, but never applied at runtime.
// rect.left = 10;

// Derive a new value instead.
const movedRect = rect.set("left", 10);
```

### Secondary toolbar no longer covers document content

The secondary toolbar reserves scrollable space while it’s open instead of overlaying the document, so content underneath it is always reachable. The space is reserved above the first page with the default toolbar placement, and below the last page when `toolbarPlacement` is `BOTTOM`.

### Performance improvements

- Content Editor startup is faster because fonts are cached and reused across editing sessions instead of being loaded again for each one.
- The thumbnails sidebar feels immediate while being resized: Thumbnails settle directly at their final position rather than animating into it, so the list no longer shifts after it renders and click targets stay steady.

### Other additions

- GdPicture is updated to 14.4.7. Refer to the GdPicture changelog for details.
- Progressive page renders that exhaust WebAssembly memory now surface a typed out-of-memory error instead of retrying through direct rendering, which prevents memory-exhaustion crash loops on very large pages.

### Collaboration and forms

- Fixes updates to annotations, comments, and form fields being silently discarded when Collaboration Permissions are enabled and the update was issued before Document Engine acknowledged the record’s creation.
- Fixes chained form field calculations not being fully recalculated when the document’s calculation order lists dependent fields before the fields they depend on.
- Fixes Document Compare requiring a trailing slash on the AI Assistant `backendUrl`.

### Rendering and editing

- Fixes washed-out colors when rendering PDFs that use CMYK transparency groups with process black or DeviceN shadings.
- Fixes dashed lines with fractional dash patterns rendering as solid lines.
- Fixes free text callout annotations sometimes rendering text too small or clipped.
- Fixes ink strokes changing after they’re completed.
- Fixes a crash on Safari and iOS 15.4–16 when rendering text containing a URL.

### User interface

- Fixes the viewer losing its scroll position when opening or closing the sidebar, which left it showing a blank page or jumping to the first page instead of staying on the current page.
- Fixes annotation placement when browser extensions load with custom toolbars.
- Fixes the loading skeleton showing its toolbar at the top when `toolbarPlacement` is set to `BOTTOM`.
- Fixes the text annotation opacity slider on mobile closing after a single step instead of following a press and drag to the chosen value.
- Fixes reopening the reply editor when returning to a comment thread with an unsaved edit.
- Fixes rich text annotation editor text selection spanning multiple nodes in the shadow DOM viewer variant.
- Fixes measurement settings modal colors for built-in and custom dark themes.

### Loading, platform, and API reference

- Fixes aborting `NutrientViewer.load()` with an `AbortSignal` hanging instead of rejecting when the SDK is rendered in an iframe.
- Fixes a `ReferenceError` in the Node SDK when applying an `importDocument` document operation on Node.js 18 and 19, which have no global `File`.
- Fixes corrupted type signatures and missing property descriptions on several API reference pages, along with the annotation class names shown for `defaultAnnotationsSidebarContent` and `defaultEditableAnnotationTypes`.

For a full list of fixes, refer to the changelog.

{% alert line="multi-line" %}
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 requires Document Engine 1.18.0 or later. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.19 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.20.0
[web sdk 1.19 release notes]: /guides/web/release-notes/1-19/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[ui-customization]: /guides/web/user-interface/ui-customization/introduction/
[supported-slots]: /guides/web/user-interface/ui-customization/supported-slots/
[javascript]: /guides/web/forms/javascript-validation/
[gdpicture-changelog]: /guides/dotnet/changelog/#14.4.7

Lists important changes for Nutrient Web SDK 1.20]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.19 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-19/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-19/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.19]]></description>
            <content:encoded><![CDATA[### Execute PDF actions programmatically

You can now execute PDF actions from your own code with `instance.executeAction()` instead of relying on a user activating them in the UI. This works with action objects returned by APIs such as `getDocumentOutline()` and `getBookmarks()`, with actions attached to link annotations, and with actions you construct yourself.

- Execution is fail-fast: Traversal of the action tree stops at the first error and the returned promise is rejected. Side effects from actions that already ran aren’t rolled back.
- In server-backed mode, JavaScript actions require an execution context. Use the `context` option to pass the triggering annotation or form field.

```js
// Execute the action of the first document outline element.
const outline = await instance.getDocumentOutline();
const firstItem = outline.first();

if (firstItem?.action) {
  await instance.executeAction(firstItem.action);
}

// Execute an action you construct yourself.
await instance.executeAction(
  new NutrientViewer.Actions.GoToAction({ pageIndex: 5 })
);

// Execute a JavaScript action with annotation context.
await instance.executeAction(linkAnnotation.action, {
  context: { type: "annotation", annotation: linkAnnotation },
  triggerEventType: "onPointerDown",
});
```

For more information, refer to the PDF actions guide.

### Line spacing for text and form field annotations

Text annotations and widget annotations now expose a `lineSpacing` property that controls the spacing between lines of text. The value is the total line height in PDF points, measured baseline to baseline, and is independent of the font size:

```js
const textAnnotation = new NutrientViewer.Annotations.TextAnnotation({
  pageIndex: 0,
  boundingBox: new NutrientViewer.Geometry.Rect({
    left: 50,
    top: 50,
    width: 300,
    height: 120,
  }),
  fontSize: 12,
  text: {
    format: "plain",
    value: "First line\nSecond line",
  },
  // Total line height in PDF points, independent of `fontSize`.
  lineSpacing: 18,
});

await instance.create(textAnnotation);
```

### Configurable Standalone page cache

In Standalone mode, the page cache is now capped at 256 MiB by default. It was previously unbounded, which allowed long viewing sessions over large documents to retain more memory than necessary. Use the new `pageCacheSizeInBytes` option to raise or lower the limit to suit your documents and target devices:

```js
NutrientViewer.load({
  // ...your existing configuration.
  pageCacheSizeInBytes: 512 * 1024 * 1024, // 512 MiB
});
```

The currently active page can still exceed this limit when that page alone requires more memory.

### Annotation tab order in Document Engine mode

`instance.getPageTabOrder()` is now supported in Document Engine mode, so you can read the keyboard navigation order of a page’s annotations and form fields with the same API in both backends. Document-defined annotation tab order requires Document Engine 1.18.0 or later. Against earlier versions, Web SDK doesn’t request the unsupported endpoint and retains fallback tab ordering. The method reports that the Document Engine version doesn’t provide the document-defined order.

### Independent callout text box positioning

Callout annotations are easier to lay out. You can now move a callout’s text box on its own by clicking and dragging it, leaving the callout line and its end point in place. A plain click still enters text edit mode, so existing editing behavior is unchanged.

### Accessibility

This release resolves a round of issues that accessibility audits flagged, and it improves how the UI behaves for assistive technology and motion-sensitive users.

- Comment threads, comment markers, and the Form Creator dialog no longer carry invalid ARIA references, so their accessible names and controls resolve correctly.
- The visibility and lock toggles in the layers sidebar now have accessible names for screen readers.
- Comment threads no longer nest a `complementary` landmark inside another landmark.
- Annotations sidebar page groups no longer reference a missing element in their ARIA label, and Document Editor page thumbnails no longer declare an ARIA description that cannot be resolved across the shadow DOM boundary. Both previously caused audits to report invalid ARIA attribute values.
- The comment sidebar animation now honors the `prefers-reduced-motion` setting.

### Localization changes

Duplicate and dotted localization keys are removed, so each string now has exactly one canonical key. **If you override any of the affected keys through custom translations, update them to the new names.**

| Old key                            | New key                            |
| ---------------------------------- | ---------------------------------- |
| `TextComparison.filterInstruction` | `TextComparison_filterInstruction` |
| `FormCreator`                      | `formCreator`                      |
| `multiline`                        | `multiLine`                        |

This release also fixes the custom color picker showing raw translation keys when using the `en-GB` locale. For more information on overriding translations, refer to the localization guide.

### Performance improvements

- Switching documents is faster because already-fetched dynamic fonts are reused instead of being downloaded again.
- Opening the annotations sidebar on large documents in Standalone mode no longer delays page thumbnails and other content from rendering.
- Standalone mode no longer preloads GdPicture for PDF `ArrayBuffer` inputs that begin with a UTF-8 byte-order mark before the PDF header.

### Other additions

- GdPicture is updated to 14.4.6.1. Refer to the GdPicture changelog for details.
- Errors raised when Document Engine rejects an annotation, comment, or form field change now include the rejection reason reported by the server.

### Memory and stability

- Fixes retained workers and memory when a document load fails, and memory retention after unloading Standalone instances.
- Fixes a memory leak where a failed GdPicture engine initialization left its web worker running, and stops the GdPicture runtime from being downloaded again on every subsequent document load after a failed preload.
- Fixes a WebAssembly stack overflow in Safari when reusing Standalone instances.
- Fixes server-backed `exportPDF` ignoring optimization, linearization, and PDF/A conformance options, and fixes PDF exports against Document Engine versions earlier than 1.12.0, which require authentication tokens in query parameters for the legacy `/pdf` endpoints.
- Fixes automatically extracted links being skipped when loading a document, and empty arrays and `null` values in annotation custom data not being preserved.

### Rendering, editing, and forms

- Fixes rich text handling in text annotations, including font sizes (fractional sizes included) changing on PDF export, reimport, and editing or when pasting formatted content from external editors, and semi-transparent pasted backgrounds.
- Fixes several rendering issues, including PDFs that combine CMYK content, spot colors, soft masks, and transparency effects rendering incorrectly, some elements not being rendered on complex pages, and appearance stream generation for text annotations containing a caron.
- Fixes form field issues, including list box and combo box fields losing all but their first option when copied, pasted, or duplicated, and focused text fields not reflecting explicit value resets.
- Fixes UI interaction issues, including the search UI opening behind an active annotation tool’s toolbar, the toolbar not reappearing when reopening a tool such as Document Crop or Measurements, moving a non-contiguous Document Editor page selection after a selected page doing nothing, and Content Editor Add Text on iOS requiring a second tap to show the keyboard.
- Fixes annotations being placed with a horizontal offset in iframe render mode (`useIframe: true`) after a sidebar is opened when the viewer container isn’t flush with the viewport’s left edge.
- Fixes `preventTextCopy` blocking text copying from the note annotation editor under the default shadow DOM rendering, the distance measurement tool creating a scale calibration when calibration was armed but not completed, and UI customization behavior for late-mounted slots and password prompt recipes, including note annotation creation now respecting `keepSelectedTool`.

For a full list of fixes, refer to the changelog.

{% alert line="multi-line" %}
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 requires Document Engine 1.18.0 or later. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.18 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.19.0
[web sdk 1.18 release notes]: /guides/web/release-notes/1-18/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[pdf-actions]: /guides/web/annotations/pdf-actions/
[localization]: /guides/web/features/localization/
[gdpicture-changelog]: /guides/dotnet/changelog/#14.4.6.1

Lists important changes for Nutrient Web SDK 1.19]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.18 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-18/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-18/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.18]]></description>
            <content:encoded><![CDATA[### Advanced content editor APIs

This release adds a programmatic content editor API so you can drive editing from your own code instead of only through the UI.

- Create and delete blocks, enter create-mode, set the selection programmatically, and insert text.
- Apply list formatting and introspect undo availability and fonts.
- Set text styles — including native strikethrough — via `instance.contentEditor.setTextStyle({ strikethrough })`, and read the active style with `getCurrentStyle()`.
- Set paragraph alignment and line spacing via `instance.contentEditor.setLayout()`, reported through `getCurrentStyle()` and `getBlock()`.

```js
const instance = await NutrientViewer.load({
  /* ...your existing configuration. */
});

// Apply strikethrough to the current selection.
instance.contentEditor.setTextStyle({ strikethrough: true });

// Set paragraph alignment and line spacing.
instance.contentEditor.setLayout({ alignment: "center", lineSpacing: 1.5 });
```

### Auto-resolve for confirmation dialogs

Confirmation dialog slots now accept an additive `autoResolve` option that skips the prompt and answers it programmatically.

- `autoResolve` accepts `"accept"` or `"reject"`, which name the *answer to the dialog* rather than a button label, so `"reject"` is uniformly safe and never discards or deletes work.
- When set, `autoResolve` takes precedence over a slot’s `render` and over the hide applied by the `minimal` UI preset.
- It’s supported on `annotations.deleteConfirm`, `contentEditor.exitConfirm`, `contentEditor.downloadConfirm`, and `reloadConfirm`.

```js
NutrientViewer.load({
  // ...your existing configuration.
  ui: {
    contentEditor: {
      // Download and continue without showing the prompt.
      downloadConfirm: { autoResolve: "accept" },
    },
    annotations: {
      // Keep the annotation instead of deleting it, with no prompt shown.
      deleteConfirm: { autoResolve: "reject" },
    },
  },
});
```

Per slot, `"accept"`/`"reject"` resolve to:

| Slot                            | `"accept"`            | `"reject"`                   |
| ------------------------------- | --------------------- | ---------------------------- |
| `annotations.deleteConfirm`     | Delete the annotation | Keep it                      |
| `contentEditor.exitConfirm`     | Save and exit         | Keep editing (don’t discard) |
| `contentEditor.downloadConfirm` | Download and continue | Dismiss without downloading  |
| `reloadConfirm`                 | Reload the document   | Keep the current document    |

### Snapping for measurement creation

Creating measurements is now more precise. Measurement tools snap while you draw, a snap indicator shows where the point will land, and you can hold a modifier key to temporarily bypass snapping when you need a freehand placement.

### Performance improvements

This release reduces latency across loading, printing, and document operations.

- Document object model (DOM) printing against Document Engine now renders all pages in a single batched request instead of one request per page.
- Initial document loading is faster because configuration requests are parallelized during `load()`.
- Text extraction, content tree retrieval, and rendering operations have lower latency.

### Simpler TypeScript imports

The SDK’s type declarations now use `export default` instead of `export =`, so importing the SDK no longer requires enabling the `allowSyntheticDefaultImports` or `esModuleInterop` compiler flags. A missing type definition for `officeConversionSettings` in the `NutrientViewer.load()` configuration object has also been added.

### Other additions

- GdPicture is updated to 14.4.5.1. Refer to the GdPicture changelog for details.
- Immutable.js is updated to version 5.

### Form field changes

- The multiselect option is removed from combo box form fields, and vertical alignment controls are removed from list box widgets in Form Creator.
- List box widgets now use their configured explicit font size.
- In Standalone mode, radio buttons are deselectable when `noToggleToOff` is disabled, and a deselected radio reports the value `Off` in both Standalone and Document Engine.

### Comments, rendering, and stability

- Fixes a range of comment editing issues, including drafts and edits losing intentional whitespace or saving empty content, content being lost when switching surfaces or deleting comments, edits closing when a reply is saved in the same thread, and typed or pasted URLs (including bare `www.` links) not becoming clickable.
- Fixes several text annotation issues, including a font-size jump when entering edit mode after resizing, reimported rich text annotations in XML Forms Data Format (XFDF) or Instant JSON not auto-fitting, cancel behavior discarding programmatic updates, and pending formatting being lost when editing empty text.
- Fixes scrolling getting trapped on the current page in Safari while selecting a text block in the content editor or editing a text or callout annotation, and built-in dialogs being unresponsive on compact mobile viewports inside a shadow DOM.
- Fixes content editor font issues, including CJK (Chinese, Japanese, Korean) text disappearing or rendering as tofu after a font-family change, incorrect glyphs for embedded subset fonts, and matching for CID Identity-H subset fonts.
- Fixes forms and export handling, including form field values not being committed before export and save; copy-and-paste of a field throwing a duplicate-name error; text form field widget styles being lost or restored incorrectly across export and reload; and checkbox, radio, and push button widget appearances and font sizes not being preserved.
- Fixes rendering issues, including rotated pages remaining blurry after zooming with next-generation page rendering, CMYK PDFs with multiply-blended transparency groups rendering washed out, and partially erased ink annotations rendering a stale appearance stream.
- Fixes server-backed sync losing image and signature annotations when a concurrent change coincided with an attachment reupload, and unhandled rejections when rapidly switching standalone documents.
- Fixes next-generation rendering issues after content editor use, including tiles failing to decode in Server mode and pages staying blurry after saves, and fixes invalid text selection fonts for documents with unusually large glyph advances.

For a full list of fixes, refer to the changelog.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later can run this release. However, `instance.exportPDF()` requires Document Engine 1.12.0 or later because earlier versions require legacy query-parameter authentication for the `/pdf` endpoint. 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. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.17 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.18.0
[web sdk 1.17 release notes]: /guides/web/release-notes/1-17/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[gdpicture-changelog]: /guides/dotnet/changelog/#14.4.5.1

Lists important changes for Nutrient Web SDK 1.18]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.17 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-17/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-17/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.17]]></description>
            <content:encoded><![CDATA[### Reactive UI slot customization

This release makes the slot-based UI customization system reactive, so custom slots stay in sync with your application state and the SDK lifecycle without manual DOM bookkeeping.

- Slot callbacks now receive a `helpers` argument that exposes `requestUpdate()`. Call it from asynchronous work, event handlers, or lifecycle hooks to ask the SDK to re-invoke your slot’s `render` with the current parameters (but not synchronously from within `render`).
- A slot’s `render` now runs once at mount and then again automatically once the SDK instance becomes available, so `getInstance()` returns the live instance without extra wiring.
- Slot lifecycle timing is more predictable: Most slots fire after instance availability, while the `loader` and `passwordPrompt` slots keep their original raw mount timing because they can render before `load()` resolves.

```js
NutrientViewer.load({
  // ...your existing configuration.
  ui: {
    commentThread: (getInstance, id, { requestUpdate }) => {
      const root = document.createElement("div");
      return {
        render: () => {
          // `getInstance()` is null until the instance is available;
          // `render` then runs again automatically once it is.
          root.textContent = getInstance() ? `Thread ${id}` : "Loading…";
          return root;
        },
        onMount: () => {
          // Rerun `render` whenever your own application state changes.
          myStore.subscribe(requestUpdate);
        },
      };
    },
  },
});
```

For more information, refer to the UI customization and supported slots guides.

### Improved text selection accuracy

This release improves text selection accuracy. In Document Engine mode, this improvement requires Document Engine 1.17.0 or later once available.

### Accessibility

Screen reader support is improved for annotations. When keyboard focus lands on a markup, ink, or shape annotation, the SDK now exposes the annotation’s referenced text, so assistive technologies announce the content the annotation refers to.

### Other additions

- GdPicture is updated to 14.4.4. Refer to the GdPicture changelog for details.

### Performance, rendering, and stability

- Fixes several Document Editor issues, including a crash when moving selected pages after a page in the same selection, inconsistent reordering when moving multiple selected pages, and a move dialog that could require two taps on mobile.
- Fixes a range of Form Creator and form field issues: Editing a field’s name no longer makes it disappear until the next click, Control/Command-click no longer silently exits the active interaction mode, Shift-click now registers on the first widget when starting a multiselection, and newly created fields can be renamed repeatedly in standalone mode.
- Fixes signature handling, including filling overlapping signature form fields, a selection flicker on filled signature fields, typed electronic signatures being cropped in RTL documents, and a raw localization key in the signature image picker.
- Fixes measurement issues, including a loupe that could stay visible after pressing Escape, fractional precision labels showing an incorrect inch suffix for non-inch units, and an error and ghost label left behind after undoing an in-progress polygon area measurement.
- Fixes several rendering issues, including thin white or colored lines in smooth background areas, squiggly text markup appearing truncated after resizing or zooming, search highlights making matched text unreadable in Safari, custom overlay items drifting from page content while scrolling, and rendering of zero-size and small pages in server-backed mode.
- Fixes text annotation autofit so disabled autofit preserves manually resized bounding boxes when changing text properties and stops text selection toolbar items from appearing in the annotation toolbar.
- Additional fixes across Instant JSON export (checkbox and radio button option labels) and standalone document loading for generic or missing MIME types.

For a full list of fixes, refer to the changelog.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later can run this release. However, `instance.exportPDF()` requires Document Engine 1.12.0 or later because earlier versions require legacy query-parameter authentication for the `/pdf` endpoint. 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. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.16 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.17.0
[web sdk 1.16 release notes]: /guides/web/release-notes/1-16/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[ui-customization]: /guides/web/user-interface/ui-customization/introduction/
[supported-slots]: /guides/web/user-interface/ui-customization/supported-slots/
[gdpicture-changelog]: /guides/dotnet/changelog/#14.4.4
[document-engine-changelog]: /guides/document-engine/changelog/#1.17.0

Lists important changes for Nutrient Web SDK 1.17]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.16 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-16/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-16/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.16]]></description>
            <content:encoded><![CDATA[### Breaking changes

This release includes one breaking change. Review the impact and restoration steps below before upgrading.

#### Keyboard shortcuts are now scoped to the viewer by default

Pre-1.16 versions captured the SDK’s keyboard shortcuts (search, print, undo, redo, zoom, and arrow-key pagination) across the entire host page, so pressing Command/Control-F anywhere opened the SDK search dialog. 1.16 makes `{ scope: "viewer" }` the default for the new `keyboardShortcutScope` option, so these shortcuts fire only while the user is interacting with the viewer.

**Impact:** Integrations that don’t set `keyboardShortcutScope` go from “shortcuts capture document-wide” to “shortcuts fire only when the user is interacting with the viewer.” This includes the initial state before the user has clicked or tabbed into the viewer, where the keystrokes now go to the browser’s native handlers (for example, Command/Control-F opens the browser’s own find dialog). Markup toolbar shortcuts (highlight, strikeout, underline, and similar) are always viewer-scoped.

**Restoring previous behavior:** Pass the explicit global form and opt every action into global capture:

```js
await NutrientViewer.load({
  // ...your existing configuration
  keyboardShortcutScope: {
    scope: "global",
    interceptedActions: Object.values(NutrientViewer.KeyboardShortcutActions),
  },
});
```

You can also capture only a subset globally and leave the rest viewer-scoped. Refer to keyboard shortcut scoping for the full set of options.

### Headless content editor API

This release adds a `contentEditor` namespace on `instance` for driving content editing programmatically, without going through the toolbar UI, together with a new `contentEditor.stateChange` event so you can react to edit-session transitions. This continues the headless direction started with the annotation APIs in 1.15.

```js
instance.addEventListener("contentEditor.stateChange", (state) => {
  // React to content editor session changes.
});
```

For more information, refer to the headless content editor and content editor API guides.

### Programmatic password handling for encrypted documents

A new `onPasswordRequired` callback on `NutrientViewer.load()` lets you resolve passwords for encrypted documents in code instead of relying on the built-in prompt. It also supports documents that use the Dedicon encryption filter.

```js
await NutrientViewer.load({
  // ...your existing configuration
  onPasswordRequired: async () => {
    // Return the password from your own UI or secret store.
    return await getDocumentPassword();
  },
});
```

For more information, refer to the password-protected documents guide.

### Keyboard shortcut scoping

The new `keyboardShortcutScope` option controls where the SDK’s keyboard shortcuts are captured. Two forms are supported.

**`viewer` (default)**

Shortcuts fire only while the user is interacting with the viewer, leaving the rest of the host page untouched:

```js
await NutrientViewer.load({
  // ...your existing configuration
  keyboardShortcutScope: { scope: "viewer" },
});
```

**`global`**

Restores document-wide capture for the actions you list in `interceptedActions`. Pass every action for the pre-1.16 behavior or a subset to capture some globally and keep the rest viewer-scoped:

```js
await NutrientViewer.load({
  // ...your existing configuration
  keyboardShortcutScope: {
    scope: "global",
    interceptedActions: [NutrientViewer.KeyboardShortcutActions.SEARCH],
  },
});
```

The available actions are `SEARCH`, `PRINT`, `ZOOM`, `UNDO`, `REDO`, and `PAGINATION`. This release also fixes Command/Control-`+`/`-` zoom shortcuts in Firefox, which previously never fired because of a browser keycode difference.

For more information, refer to the keyboard shortcuts guide.

### AI Assistant over HTTP MCP servers

AI Assistant can now connect to HTTP MCP servers. A new public `AIAssistant.MCPHttpServerConfig` type and the `AIAssistant.AgentConfiguration.mcps` option let you wire the agent up to external tools and data sources you host.

For more information, refer to the AI Assistant integration and AI agent tools guides.

### Opt-in debug logging

A new opt-in debug logging mode surfaces detailed diagnostics to help track down initialization failures and other hard-to-reproduce issues. It’s off by default and safe to leave out of production builds.

For more information, refer to the debug logging guide.

### Other additions

- `ToolbarItemType` is now part of the public API, and the API documentation lists every valid toolbar item type value.
- GdPicture is updated to 14.4.2. Refer to the GdPicture changelog for details.

### Performance, rendering, and stability

- Fixes memory leaks that caused cumulative growth in DOM nodes, event listeners, and GPU memory across load and unload cycles in standalone mode, including cleanup of change-manager subscriptions, backend references, and electronic-signature font face style tags on unload.
- Fixes an intermittent hang or blank render when loading multiple viewer instances concurrently in standalone mode.
- Fixes an issue where the new page rendering architecture could display stale page content after zooming or scrolling.
- Hardens XHTML sanitization for imported comments in standalone mode, closing a clickjacking gap that previously allowed inline styles and other disallowed markup.
- Fixes password stripping when exporting PDFs in server-backed mode.
- Fixes several core rendering and geometry issues, including DeviceCMYK transparency groups with multiply and overlay blend modes rendering too dark, clipped emojis in plain-text free text annotations, a crash on PDFs with malformed GoTo or GoToR link destinations, and page-margin and measurement-snapping errors on documents whose `CropBox` or `MediaBox` have a non-zero origin.
- Additional fixes across the content editor, custom stamps, form fields, comments, measurement annotations, indexed full-text search, and dynamic font downloading.

For a full list of fixes, refer to the changelog.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later can run this release. However, `instance.exportPDF()` requires Document Engine 1.12.0 or later because earlier versions require legacy query-parameter authentication for the `/pdf` endpoint. 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. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.15 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.16.0
[web sdk 1.15 release notes]: /guides/web/release-notes/1-15/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[keyboard-shortcuts-guide]: /guides/web/knowledge-base/add-custom-keyboard-shortcuts/
[keyboard-shortcut-scoping]: #keyboard-shortcut-scoping
[password-protected-guide]: /guides/web/features/password-protected-pdfs/
[headless-content-editor]: /guides/web/headless/content-editor/
[content-editor-api]: /guides/web/editor/content-editor-api/
[ai-assistant-guide]: /guides/web/ai-assistant/integrate-with-ai-assistant/
[ai-agent-tools-guide]: /guides/web/ai-assistant/ai-agent-tools/
[debug-logging-guide]: /guides/web/troubleshooting/debug-logging/
[gdpicture-changelog]: /guides/dotnet/changelog/#14.4.2

Lists important changes for Nutrient Web SDK 1.16]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.15 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-15/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-15/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.15]]></description>
            <content:encoded><![CDATA[### Breaking changes

This release includes two breaking changes. Review the impact and restoration steps below before upgrading.

#### Document loading screen is now the skeleton UI

Pre-1.15 versions showed a hardcoded progress spinner/bar while documents loaded, with no API to configure it. 1.15 introduces the new `ui.loader` option together with a new `skeleton` loader — a realistic placeholder of the viewer layout that reduces perceived load time and makes the skeleton the default. Any integration upgrading from 1.14 or earlier will see the skeleton during document load instead of the previous spinner, without changing any code.

**Impact:** No code change is required for the new behavior, but the loading UI users see during `NutrientViewer.load()` is visually different. Custom CSS or visual regression tests that asserted against the previous spinner may need updates.

**Restoring previous behavior:** Pass `{ type: "progress" }` to keep the pre-1.15 spinner:

```js
await NutrientViewer.load({
  // ...your existing configuration
  ui: { loader: { type: "progress" } },
});
```

Refer to configurable loader UI for the full set of options, including custom slot callbacks.

#### UI customization slot callbacks now receive `getInstance()`

The first argument to every `ui.*` slot callback changed from a captured `instance` reference to a `getInstance()` accessor. Call `getInstance()` at the point of use — typically inside `render` or an event handler — to read the latest viewer instance.

**Impact:** Existing `ui.*` slot callbacks that used the first argument as a synchronous `instance` reference will break at runtime once upgraded. Preload slots (`ui.loader`, `ui.passwordPrompt`) previously received `null` here because the viewer hadn’t finished loading; with `getInstance()`, the same callback can read the live instance from any render call or event handler that fires after `NutrientViewer.load()` resolves.

**Migration:** Update each callback to call `getInstance()` at the point of use.

Before:

```js
NutrientViewer.load({
  ui: {
    tools: {
      main: (instance, id) => ({
        render: () => createToolbar(instance),
      }),
    },
  },
});
```

After:

```js
NutrientViewer.load({
  ui: {
    tools: {
      main: (getInstance, id) => ({
        render: () => createToolbar(getInstance()),
      }),
    },
  },
});
```

The change applies to every `ui.*` slot, including:

- Preload slots — `ui.loader`, `ui.passwordPrompt`.
- Postload slots — `ui.tools.main`, `ui.tools.contextual`, `ui.annotations.*`, `ui.signatures.*`, `ui.search`, `ui.documentEditor`, `ui.commentThread`, `ui.sidebar.*`.

### Headless annotation APIs

This release introduces an `annotations.*` namespace on `instance` for working with annotations programmatically, organized by annotation type. Each sub-namespace exposes type-specific operations and shares a common selection, note, and clipboard infrastructure — usable without mounting the full viewer UI:

- `annotations.ink`
- `annotations.link`
- `annotations.measurement`
- `annotations.redaction`
- `annotations.shape`
- `annotations.textMarkup`
- `annotations.text`

The shared infrastructure is extensible — additional annotation types can plug into the same primitives. This is the foundation for richer headless and automation workflows. For more information, refer to the headless annotations overview, headless measurement annotations, and headless redaction annotations. Let us know through our support form which patterns you’d like to see expanded next.

### Cancelable load and conversion operations

`NutrientViewer.load()`, `convertToPDF()`, `convertToOffice()`, and `populateDocumentTemplate()` now accept an `AbortSignal` to cancel in-flight operations. This is useful when users navigate away mid-load or you need to terminate a slow conversion:

```js
const controller = new AbortController();
const instance = await NutrientViewer.load({
  // ...your existing configuration
  signal: controller.signal,
});

// Later, to cancel:
controller.abort();
```

For more information, refer to the viewer troubleshooting, Office-to-PDF conversion, PDF-to-Office conversion, and Word template generation guides.

### Configurable loader UI

A new `ui.loader` option controls what users see while a document loads. Three forms are supported:

**`skeleton` (default)** — A realistic placeholder of the viewer layout that reduces perceived load time:

```js
await NutrientViewer.load({
  // ...your existing configuration
  ui: { loader: { type: "skeleton" } },
});
```

**`progress`** — The indeterminate spinner with a determinate progress bar (the pre-1.15 default):

```js
await NutrientViewer.load({
  // ...your existing configuration
  ui: { loader: { type: "progress" } },
});
```

**Slot callback** — Fully replace the loader with custom DOM. Because the loader renders before `NutrientViewer.load()` resolves, `getInstance()` may return `null` inside this slot; use it for loading UI only:

```js
await NutrientViewer.load({
  // ...your existing configuration
  ui: {
    loader: (getInstance, id) => ({
      render: () => {
        const div = document.createElement("div");
        div.innerText = "Loading your document...";
        return div;
      },
    }),
  },
});
```

To hide the loader entirely, return `null` from `render`: `(getInstance, id) => ({ render: () => null })`.

### Whitespace-tolerant search

A new opt-in, `SearchType.WORD_BASED`, makes `instance.search()` resilient to whitespace inconsistencies in extracted PDF text. The mode strips Unicode space variants (NBSP, em/en/thin spaces, ideographic space, etc.) plus tab/newline/CR from both the query and the document before matching, so multiline phrases that cross tables, columns, or line wraps with stray whitespace match cleanly. Annotation contents are matched with the same algorithm. Punctuation is preserved on both sides, and case-insensitive search (the default) now case-folds non-ASCII letters too — `"MÖCHTEN"` matches `"möchten"`.

```js
const results = await instance.search("Smith, John", {
  searchType: NutrientViewer.SearchType.WORD_BASED,
});
```

Default `instance.search()` behavior is unchanged. Additionally, the existing smart-search regex now tolerates a single space immediately before a line break, fixing cases where PDF text extraction inserts a trailing space at line wraps and a clean-newline query failed to match.

{% alert line="single-line" icon="dotted/info" %}
`SearchType.WORD_BASED` is available in Web SDK standalone mode immediately. Server-backed mode requires Document Engine 1.16.0 or later.
{% /alert %}

For more information, refer to the text search and built-in search UI guides.

### Performance, fonts, and stability

- Dynamic font downloading and font substitution now work for linearized PDF loads, eliminating font-related fallbacks during progressive loading.
- A new API lets you control the visual rendering order of annotations on a page via a custom comparator function.
- Document Crop mode now supports keyboard input — arrow keys draw the crop region, Enter confirms, and Escape cancels.
- The standalone JWT signing service now forwards the `flatten` flag consistently from `prepareSign` to the `/sign_hash` request, producing valid signatures when `instance.signDocument()` is called with `flatten: true`.
- Fixes a regression introduced in 1.14.0 where cross-user updates to non-comment annotations could be rejected by Document Engine with `invalid_anonymity_update`, blocking collaborative editing of existing annotations.
- Additional fixes across RTL viewer trackpad scrolling and scrollbar visibility, IME composition in custom stamp text fields, content editor text drag-selection on Windows, ligature text selection, redaction font sizing, Arabic rich-text free text appearance streams, and several content editor and form creator edge cases.

For more information, refer to the font substitution, linearized downloads, crop, and annotation customization guides.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later can run this release. However, `instance.exportPDF()` requires Document Engine 1.12.0 or later because earlier versions require legacy query-parameter authentication for the `/pdf` endpoint. In server-backed mode, `SearchType.WORD_BASED` requires Document Engine 1.16.0 or later. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For more information, refer to the UI customization introduction, supported slots reference, and slot examples guides.

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.14 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.15.0
[web sdk 1.14 release notes]: /guides/web/release-notes/1-14/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[searchtype-api]: /api/web/enums/NutrientViewer.SearchType.html
[abortsignal]: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
[ui-loader-api]: /api/web/interfaces/UI.Configuration.html#loader
[support-form]: https://support.nutrient.io/hc/en-us/requests/new
[viewer-troubleshooting]: /guides/web/viewer/troubleshooting/
[office-to-pdf]: /guides/web/conversion/office-to-pdf/
[pdf-to-office]: /guides/web/conversion/pdf-to-office/
[from-word-template]: /guides/web/pdf-generation/from-word-template/
[headless-overview]: /guides/web/headless/
[headless-measurement]: /guides/web/headless/measurement/
[headless-redaction]: /guides/web/headless/redactions-from-selection/
[ui-customization-introduction]: /guides/web/user-interface/ui-customization/introduction/
[supported-slots]: /guides/web/user-interface/ui-customization/supported-slots/
[ui-slot-examples]: /guides/web/user-interface/ui-customization/examples/
[text-search-guide]: /guides/web/features/customized-search/
[built-in-search-ui]: /guides/web/search/built-in-ui/
[font-substitution-guide]: /guides/web/viewer/fonts/substitution/
[linearized-downloads-guide]: /guides/web/viewer/linearized-downloads/
[crop-guide]: /guides/web/editor/page-manipulation/crop/
[annotation-customization-guide]: /guides/web/annotations/custom-rendered-annotations/

Lists important changes for Nutrient Web SDK 1.15]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.14 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-14/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-14/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.14]]></description>
            <content:encoded><![CDATA[### Linearized PDF loading enabled by default

Starting with 1.14, linearized PDF downloading works without any extra configuration when your server supports range requests. Existing integrations no longer need to pass `allowLinearizedLoading: true` in `NutrientViewer.load()`.

If you need to opt out, set `allowLinearizedLoading: false`. For setup details and server requirements, refer to the linearized downloads guide.

### UI customization slots

This release introduces a slot-based UI customization system that gives fine-grained control over every part of the viewer interface. Components are organized by feature domain (tools, annotations, content editor, signatures, stamps, measurements, document comparison, form creator, and sidebar). Each slot supports subslot customization (header, body, footer) for partial replacement without overriding the entire component.

To get started quickly, use the new `minimal` preset to hide all UIs and selectively restore only the components you need:

```js
await NutrientViewer.load({
  // ...your existing configuration
  ui: { preset: "minimal" },
});
```

For full control, configure individual slots to replace, extend, or hide specific components. See the UI configuration API reference for the complete list of available slots. This is a significant new system and we’re excited to get it in front of real integrations. We’d love to hear your feedback on what works, what doesn’t, and which slots you’d like to see extended in future releases — share it with us through our support form.

### Accessibility and keyboard support

This release adds keyboard support for creating widget annotations in form designer mode and for selecting multiple annotations via rectangular area selection. Combined with the Content Editor shortcuts for bold (Control/Command-B) and italics (Control/Command-I), keyboard-driven workflows continue to improve across the SDK.

### Temporary storage for PDF downloads

When loading a PDF from a URL in standalone mode, Nutrient can now use the browser’s origin private file system (OPFS) as temporary storage for the downloaded document data instead of keeping it entirely in browser memory. This reduces peak RAM usage for larger documents.

This behavior is automatic by default. Use the new `tempStorage` configuration option to control it. Set `"memory"` to keep the previous behavior, or `"opfs"` to prefer OPFS regardless of file size. Refer to the temporary storage guide for details.

### Programmatic OCG layer creation

A new `instance.createLayer()` API lets you create optional content group (OCG) layers programmatically, and `flattenAnnotations` now accepts a `targetLayerId` option. Together, these enable exporting PDFs with per-user togglable annotation layers.

### Rich stamp annotations

Stamp annotations now support multiline text with custom font styling and embedded images. New properties include `multiline`, `font`, `fontSize`, `fontColor`, `isBold`, `isItalic`, `imageAttachmentId`, `imageContentType`, and `imagePosition` for controlling image placement within the stamp text flow.

{% alert line="single-line" %}
Server-backed rendering of rich stamp properties currently requires a nightly build of Document Engine (the 1.16+ line is not publicly released yet). On publicly available Document Engine versions (up to 1.15.1), the new properties are ignored and stamps fall back to basic rendering. Standalone/Web-only mode supports rich stamps immediately.
{% /alert %}

### Strict Content Security Policy support

For environments with strict Content Security Policy rules that require nonce-based `style-src` and `script-src` directives, a new `nonce` configuration option lets you pass a nonce value that Nutrient applies to its injected styles and scripts.

### Performance and stability

- Content Editor text block movement is noticeably faster for complex documents.
- PDF redaction stability improves for documents with nested shared forms, reducing memory spikes and incomplete redactions.
- Rendering performance improves for PDFs with large content streams.
- A progressive memory leak when repeatedly loading and unloading documents is fixed.
- Several race conditions around document loading and unloading are resolved, including a standalone deadlock when `load()` is called twice in quick succession.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later can run this release. However, `instance.exportPDF()` requires Document Engine 1.12.0 or later because earlier versions require legacy query-parameter authentication for the `/pdf` endpoint. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.13 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.14.0
[web sdk 1.13 release notes]: /guides/web/release-notes/1-13/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[linearized downloads]: /guides/web/viewer/linearized-downloads/
[ui-preset-example]: /api/web/modules/UI.html#example-3
[ui-configuration-api]: /api/web/interfaces/UI.Configuration.html
[opfs]: https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system
[temp-storage-guide]: /guides/web/open-a-document/temp-storage/
[tempstorage-api]: /api/web/interfaces/Configuration.html#tempstorage
[nonce-api]: /api/web/interfaces/Configuration.html#nonce
[createlayer-api]: /api/web/classes/NutrientViewer.Instance.html#createlayer
[support-form]: https://support.nutrient.io/hc/en-us/requests/new

Lists important changes for Nutrient Web SDK 1.14]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.13.1 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-13-1/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-13-1/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Nutrient Web SDK 1.13.1 release notes — security patch for high-severity libpng CVEs.]]></description>
            <content:encoded><![CDATA[### Security

This release resolves the following vulnerabilities in libpng:

- **CVE-2026-33416** (CVSS 7.5) — A denial-of-service vulnerability in libpng 1.6.55.
- **CVE-2026-33636** (CVSS 7.6) — A potentially exploitable vulnerability in libpng 1.6.55.

Both are resolved by updating to libpng 1.6.56. No API changes or migration steps are required.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later can run this release. However, `instance.exportPDF()` requires Document Engine 1.12.0 or later because earlier versions require legacy query-parameter authentication for the `/pdf` endpoint. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

[changelog]: /guides/web/release-notes/changelog/#1.13.1
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility

Nutrient Web SDK 1.13.1 release notes — security patch for high-severity libpng CVEs.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.13 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-13/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-13/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.13]]></description>
            <content:encoded><![CDATA[### Canvas rendering and performance

This release adds a next-generation page rendering architecture that improves page loading and zooming responsiveness. The feature is currently in beta and can be enabled via the `pageRendering` configuration:

```js
await NutrientViewer.load({
  // ...your existing configuration
  pageRendering: "next",
});
```

In our benchmarks, time to first page render is 10 percent quicker and zooming is 60 percent faster. The new architecture has gone through a lot of internal testing already, and we’re excited to get it in the hands of users for real-world testing and feedback. We recommend trying it out with your documents and sharing any feedback or issues you encounter.

### Fonts and text fidelity

Page rendering now supports both dynamic fonts and font substitutions:

- Use dynamic font loading to fetch missing fonts on demand (see the default fonts bundle).
- Use custom fonts when you want fonts loaded up front.
- Use font substitution to map source fonts (for example, `Times*`) to preferred alternatives during rendering.

With 1.13, dynamic font loading now applies to page rendering. You can start with the default fonts bundle or generate your own with the nutrient-font-tool. If a required font is missing and available in your configured bundle, the SDK downloads it before rendering the page. This improves fidelity for documents with non-embedded fonts while avoiding unnecessary upfront downloads.

This release also extends font substitution to page rendering. Font substitution now works together with dynamic font loading: Substitutions are applied during rendering, and missing target fonts can be resolved from your configured dynamic font bundle. You can define substitution rules (for example, mapping `Times*` to your preferred serif font) and have them applied consistently across rendered page content.

### Keyboard accessibility and WCAG compliance

This release makes major strides in accessibility. Content Editor now supports Control/Command-C, Control/Command-X, and Control/Command-V shortcuts for copying, cutting, and pasting entire text blocks, while line, shape, text, and callout annotations can now be created entirely with the keyboard. For WCAG compliance, toolbar button touch targets meet the minimum of 24×24 px, and the search UI announces minimum character requirements to screen readers. This release also fixes several focus management issues, including focus restoration when closing the search panel, focus loss after drag-and-drop reorder in the Document Editor, and annotation selection interfering with other focusable elements.

### Content editing and document templates

New APIs allow programmatic management of content editing sessions, and `populateDocumentTemplate()` now supports image substitution. On the stability side, this release fixes a content editing crash caused by embedded fonts with empty or null font spans, and it ensures tagged PDF text placement is preserved in the correct content stream graphics state.

### Performance and stability

Rendering performance sees notable improvements: First-page rendering for linearized PDFs is faster thanks to parallel byte range prefetching, and text comparison with the `wordLevel` option is significantly more responsive for large diffs through virtualization. This release also resolves multiple race conditions, including stale widget appearance streams after rapid form field updates, container reuse errors when switching documents, and AI Assistant MCP tools disappearing during quick document switches. For server-backed deployments, JSON Web Token (JWT) refresh is now supported via `onAuthFailed` and `setSession`.

### PDF processing and export fixes

Several PDF processing edge cases are addressed in this release. XFDF export no longer truncates annotations containing Latin-1 encoded text with embedded null bytes, and document merging now handles malformed `StructTreeRoot` entries, along with document-level JavaScript that modifies form fields. Full-text search returns results for queries containing special characters like `&`, `/`, `:`, or `+`. Rendering fixes include corrected ink highlighter export with multiply blend mode backgrounds and more consistent rich-text annotation wrapping across export and reimport.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later can run this release. However, `instance.exportPDF()` requires Document Engine 1.12.0 or later because earlier versions require legacy query-parameter authentication for the `/pdf` endpoint. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.12 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/release-notes/changelog/#1.13.0
[web sdk 1.12 release notes]: /guides/web/release-notes/1-12/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[dynamic font loading]: /guides/web/viewer/fonts/dynamic-fonts/
[nutrient-font-tool]: https://github.com/PSPDFKit/nutrient-font-tool
[custom fonts]: /guides/web/features/custom-fonts/
[font substitution]: /guides/web/viewer/fonts/substitution/
[page-rendering-api]: /api/web/interfaces/Configuration.html#pagerendering
[default-fonts-bundle]: /guides/web/viewer/fonts/dynamic-fonts/#default-fonts-bundle
[support]: /support/request/

Lists important changes for Nutrient Web SDK 1.13]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.12 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-12/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-12/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.12]]></description>
            <content:encoded><![CDATA[### Document Editor and UI reliability

Document Editor Save and Cancel actions now stay visible in constrained layouts, and the bottom UI cutoff on iPad in landscape orientation is fixed. Page navigation cursor feedback is clearer for per-spread pagination, and link popovers now expose distinct view and edit class names for easier theming.

### Commenting and annotation editing

Comment links without a protocol now open as external links instead of relative URLs. Draft comments no longer override each other, and typing focus stays in the active thread when multiple drafts are open. Plain text annotations are more stable during editing, with font size persistence and bounding box sizing fixes.

### Viewer interaction and accessibility

`setViewState` no longer steals focus from external elements in iframe mode, and toolbar focus no longer jumps to the last item when reentering via Tab. Additionally, screen reader arrow navigation regressions in JAWS/NVDA are fixed.

### Document processing and PDF fidelity

Brotli-compressed PDFs are now supported, and PDF JavaScript actions (`OpenAction` and `pageNum`) now execute reliably. Text extraction handles typographic ligatures more accurately. Redactions and markup remain aligned after margin changes, and multipage TIFFs respect per-page orientation.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.11 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.12.0
[web sdk 1.11 release notes]: /guides/web/release-notes/1-11/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility

Lists important changes for Nutrient Web SDK 1.12]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.11 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-11/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-11/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Lists important changes for Nutrient Web SDK 1.11]]></description>
            <content:encoded><![CDATA[### Commenting and annotation UI fixes

This release improves the commenting experience, including fixing deletion from the annotations sidebar in constrained layouts and preventing duplicate `@` symbols when editing comments containing user mentions.

We also addressed several user interface (UI) issues, including signature image previews in iframe mode, dialog positioning in scrolled/offset containers, and annotation interactions in RTL mode with the sidebar open.

### Accessibility and permission improvements

We fixed keyboard navigation regressions for screen readers (JAWS/NVDA) and improved keyboard access in the search UI by making the clear button focusable.

We also fixed an issue where users without permission could open the signature dialog using the keyboard, and prevented locked/read-only note annotations from being moved via keyboard and mouse wheel interactions.

### Printing and conversion

Form field values are now correctly updated before print preview in situations where a field hasn’t been blurred. We also fixed `convertToPdf()` failing when a document is passed as an object URL.

### Instant JSON and PDF fidelity fixes

Instant JSON import/export now preserves form field IDs more consistently, which helps keep subsequent exports stable after importing.

This release also includes multiple PDF fidelity fixes, including improvements to highlight geometry in tight line heights, correct handling of ligatures during text selection and highlight export, and improved automatic link extraction.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.10 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.11.0
[web sdk 1.10 release notes]: /guides/web/release-notes/1-10/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility

Lists important changes for Nutrient Web SDK 1.11]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.10 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-10/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-10/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Release notes for Nutrient Web SDK 1.10 outlining key improvements, fixes, API updates, and upgrade steps for existing integrations.]]></description>
            <content:encoded><![CDATA[### Performance improvements for large documents

This release includes performance enhancements when working with documents containing many pages. The thumbnails sidebar and document editor thumbnails now load much faster and more efficiently, making large documents easier to navigate.

Additionally, we removed the smooth scrolling animation when the thumbnail sidebar opens, ensuring it immediately displays the thumbnail of the page currently in the viewport. This eliminates the waiting time users previously experienced when opening the sidebar with documents containing hundreds of pages.

### Annotation color and styling improvements

This release includes fixes for annotation color handling when using custom color presets. When you configure `annotationToolbarColorPresets`, programmatically created annotations now correctly respect the colors you specify.

We also fixed an issue with text annotations with transparent backgrounds when using custom color presets. Annotation presets also now correctly maintain font styles (bold, italic, underline), ensuring that saved presets maintain their intended formatting when restored.

### Print preview improvements

Print preview functionality has been improved in DOM mode. Additionally, we fixed some iOS Safari-specific issues in print preview.

### UI and accessibility enhancements

This release includes improvements to the user interface and accessibility. Tooltips and aria-labels in the annotations sidebar and comment threads have been enhanced to provide clearer guidance and better screen reader support. We also made improvements in the scrolling behavior for modals.

### Annotation behavior fixes

This release resolves several annotation-related issues. We made some fixes in link annotations to improve the clicking behavior. The rendering of text annotations has been improved for rotated pages. We also made some Android-specific improvements to text annotations to prevent data loss during editing. Text and callout annotations have also been improved to prevent overflow beyond page boundaries when editing.

### Document Editor improvements

We fixed some issues in custom Document Editor toolbar items with icons.

### Form field and document processing improvements

This release enhances form field handling. We fixed some issues in form fields with additional actions. Radio and checkbox options are improved to work even when PDFs have inconsistent option lists.

### Document loading improvements

File type detection has been enhanced to correctly handle Content-Type headers that include charset or boundary parameters, improving compatibility with various server configurations.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.9 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.10.0
[web sdk 1.9 release notes]: /guides/web/release-notes/1-9/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility

Release notes for Nutrient Web SDK 1.10 outlining key improvements, fixes, API updates, and upgrade steps for existing integrations.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.9 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-9/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-9/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Nutrient Web SDK 1.9 release notes summarizing feature updates, bug fixes, viewer enhancements, and guidance for smooth upgrades.]]></description>
            <content:encoded><![CDATA[### Content editor

The content editor now enables you to reuse fonts from the document itself. This means if your PDF has embedded fonts, when you edit text, the new text will look exactly like the surrounding text.

{% alert line="single-line" %}
Some embedded fonts (“subset fonts”) only have a limited amount of characters included, in which case, the content editor will fall back to a different font. The fallback font can be adjusted using the `contentEditingFontMatcher` callback.
{% /alert %}

The content editor now also supports preserving accessibility tags when editing text, ensuring documents remain accessible after modifications.

### Simplified deployment with CDN-hosted assets

Starting with this release, the previous behavior for `baseUrl` when it isn’t set is deprecated and will result in a warning. Web SDK will transition to use CDN-hosted assets by default in the future, but you can opt in to using them right now by setting `useCDN: true` in your configuration. This update simplifies setup by removing the need to manually copy or manage assets locally. For organizations that prefer to self-host assets, this option remains available and can be configured as described in the self-host assets guide.

### Password-protected PDFs in AI Assistant

Starting with this release, AI Assistant can now process password-protected PDFs. This enhancement expands the range of documents that can be analyzed securely and doesn’t require any additional setup. AI Assistant automatically uses the same password configuration already provided when opening a document, ensuring a seamless and secure experience.

### Update UI customization configuration at runtime

Starting with this release, Web SDK introduces the `Instance.setUI` method for updating user interface (UI) configuration slots at runtime, enabling a more dynamic user experience. For detailed instructions and examples, refer to the set UI customization configuration guide.

### New supported file type

Nutrient Web SDK 1.9 adds support for converting and opening text files (`.txt`) with the corresponding license component. This enhancement broadens the range of document types that can be viewed and edited within the SDK.

### Performance and stability improvements

This release includes numerous fixes and enhancements aimed at improving performance and stability across the SDK.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.8 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.9.1
[web sdk 1.8 release notes]: /guides/web/release-notes/1-8/
[`contenteditingfontmatcher`]: /api/web/interfaces/Configuration.html#contenteditingfontmatcher
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[self host guide]: /guides/web/self-host-assets/
[setui guide]: /guides/web/user-interface/ui-customization/set-ui/
[txt format]: /guides/web/conversion/text-to-pdf/

Nutrient Web SDK 1.9 release notes summarizing feature updates, bug fixes, viewer enhancements, and guidance for smooth upgrades.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.8 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-8/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-8/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Review Nutrient Web SDK 1.8 changes with new APIs, stability fixes, performance improvements, and recommendations for upgrading projects.]]></description>
            <content:encoded><![CDATA[### Accessibility improvements

This release brings significant improvements to accessibility across the SDK, ensuring a more inclusive experience for all users. Measurement tools and the measurement annotation toolbar are now more accessible and customizable, making it easier for users to interact with documents. Widget annotations in Form Creator and Form Designer modes now offer enhanced keyboard accessibility, enabling smoother navigation and interaction without relying on a mouse.

Additionally, the SDK now preserves accessibility information when adding or flattening annotations in documents that already support PDF/UA standards. By automatically inserting the necessary tags, we ensure that assistive technologies can properly interpret document content, helping maintain PDF/UA compliance, and improving compatibility for users with disabilities.

### AI document helpers

We’ve added several new features to make working with AI-powered document functionality more straightforward. The SDK now exposes `NutrientViewer.isAIDocumentComparisonResult` and `NutrientViewer.isAIDocumentAnalysisResult`, along with `NutrientViewer.AIComparisonPhase`. They let you check the type of AI document results and verify the status of AI text comparison operations. These additions give developers more control and insight when integrating AI-driven features into their workflows, making it easier to handle AI-generated insights and comparisons reliably.

### Performance and stability improvements

This release includes numerous fixes and enhancements aimed at improving performance and stability across the SDK. We’ve addressed memory leaks when using custom fonts in standalone mode and fixed issues with text selection in multicolumn documents. Various rendering and annotation issues have been resolved, including correct handling of RTL text, Arabic fonts, and dynamic font loading.

Other improvements include enhanced support for search functionality, proper rendering of comments and annotations, prevention of crashes when repairing PDFs with missing structures, and better handling of bookmark relocation and outline editing. These changes result in a more robust, reliable experience for developers and end users alike.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.7 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.8.0
[web sdk 1.7 release notes]: /guides/web/release-notes/1-7/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[isaidocumentcomparisonresult]: /api/web/functions/NutrientViewer.isAIDocumentComparisonResult.html
[isaidocumentanalysisresult]: /api/web/functions/NutrientViewer.isAIDocumentAnalysisResult.html
[aicomparisonphase]: /api/web/enums/NutrientViewer.AIComparisonPhase.html

Review Nutrient Web SDK 1.8 changes with new APIs, stability fixes, performance improvements, and recommendations for upgrading projects.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.7 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-7/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-7/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Nutrient Web SDK 1.7 release notes covering new features, bug fixes, UI polish, and upgrade guidance for production deployments.]]></description>
            <content:encoded><![CDATA[### UI customization with slots

This release includes some improvements to the UI customization API introduced in version 1.6:

- Support for new UI customization slots in comments and comment threads.
- Support for building custom sidebars.

You can learn more about UI customization slots in our UI slots customization guide.

### UI and interaction improvements

This release includes several refinements to the user interface and user experience, outlined below.

#### Toolbar interaction enhancements

We improved interaction handling for custom input elements in the toolbar, ensuring custom components integrate seamlessly with the existing toolbar functionality and provide consistent behavior across different input types.

#### Annotation behavior fixes

We made several annotation-related improvements:

- Note annotations now properly disable dragging in read-only mode, preventing unintended modifications when documents are in read-only state.
- Overriding the `onPress` handler for annotation toolbar items will now work for components using popovers (such as select and combo box elements).

#### Dialog and interface improvements

- The stored signatures dialog now takes up the full width of its container, providing better visual consistency and improved usability.
- Document MIME type detection has been improved to improve format identification during the loading process.
- The edit bookmark button now functions correctly when clicked, resolving an issue where the button appeared inactive.

### Document events and state tracking

This release includes a couple of important fixes and improvements to enhance developer experience when working with documents.

- The `applyRedactions` operation is now correctly passed in the `document.change` event, ensuring all document modifications are properly tracked and reported through the event system.
- The `document.saveStateChange` listener is now also called after creating invalid annotations (such as empty text-valued text annotations), ensuring consistent state tracking across annotation creation scenarios.

### Nightly builds on NPM

Testing Nutrient Web SDK’s nightly builds for upcoming features or fixes has now been made even easier, thanks to the new @nightly tag available for the @nutrient-sdk/viewer npm package. This tag points to today’s build. Moreover, older nightly builds will be permanently available from now on. Here’s how to install:

```
npm install @nutrient-sdk/viewer@nightly
```

### Bug fixes and stability improvements

This release addresses numerous issues that improve overall SDK stability and user experience.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.6 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.7.0
[web sdk 1.6 release notes]: /guides/web/release-notes/1-6/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[ui-customization]: /guides/web/user-interface/ui-customization/introduction/#slots

Nutrient Web SDK 1.7 release notes covering new features, bug fixes, UI polish, and upgrade guidance for production deployments.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.6 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-6/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-6/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover Nutrient Web SDK 1.6 updates, including API improvements, annotation fixes, performance gains, and migration notes for upgrades.]]></description>
            <content:encoded><![CDATA[### New API for UI customization

This release introduces a new API for customization. Currently, this support is added only for comment threads and will be extended to other user interface (UI) elements in future releases. Refer to the UI customization guide to get started.

### Improved rich text paste functionality

We’ve enhanced the rich text paste experience with support for unformatted paste using `Cmd+Shift+V` (or `Ctrl+Shift+V` on Windows/Linux). This feature enables users to paste content from external sources while stripping all formatting, ensuring consistent text appearance within annotations. The improved paste functionality also resolves issues where annotation values weren’t properly synced after copy/paste operations from different sources, ensuring data consistency across all rich text annotations.

### Font matching and embedding improvements

A new `Configuration#contentEditingFontMatcher` configuration option has been added, allowing developers to customize how fonts are matched during content editing operations. This enhancement provides greater control over font selection and ensures consistent typography across different document workflows.

We’ve also improved font embedding when working with PDF standard fonts, resulting in better compatibility when documents are viewed in external PDF viewers. This improvement ensures documents maintain their intended appearance across different platforms and applications.

### Enhanced form capabilities

Radio buttons and checkboxes now support solid and dashed border styles.

### Document handling and performance improvements

Version 1.6 brings several enhancements to core document processing capabilities, improving both functionality and performance.

#### Improved document rendering stability

Rendering and document stability have been further enhanced in this release, resulting in a smoother experience when working with large and complex documents:

- Rendering performance has been optimized for documents with more than 100 pages, ensuring smooth navigation and interaction even at scale.
- Comment threads now display more intuitively, maintaining clear visibility of page content without overlap.
- Page-ordering operations in Document Editor are now more reliable, especially when moving multiple selected pages at once.
- Annotation selection in `PER_SPREAD` pagination mode is now handled more seamlessly, providing a more consistent editing workflow.

#### Comment display improvements

A new `ViewState#commentDisplay` property has been added to provide developers with greater control over how comments are displayed in the UI. This enables you to control whether comments are displayed as a popover or as a sidebar.

#### Consistent events

We’ve improved the behavior of callout annotations to match text annotation behavior — events now fire only on blur with non-empty content, providing a more consistent user experience across different annotation types. Text annotation create events have also been refined to prevent firing on toolbar property changes for empty annotations.

#### Search and accessibility improvements

The search input has been improved to prevent text clipping on smaller screens, ensuring better usability across different device sizes. We’ve also resolved issues where comments wouldn’t be visible on certain pages when `Configuration#isEditableComment` returned `true`.

### Security and certificate handling

Version 1.6 includes improvements to digital signature handling and certificate management:

- Enhanced certificate chain information in the `pspdfkit/signature-info` Instant JSON type, providing more comprehensive signature verification data.
- Improved handling of elliptic curve keys (ECDSA) during document signing operations, resolving compatibility issues with certain cryptographic implementations.

### Bug fixes and stability improvements

This release addresses numerous issues that improve overall SDK stability and user experience.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.5 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.6.0
[web sdk 1.5 release notes]: /guides/web/release-notes/1-5/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[`viewstate#commentdisplay`]: /api/web/classes/NutrientViewer.ViewState.html#commentdisplay
[`configuration#contenteditingfontmatcher`]: /api/web/interfaces/Configuration.html#contenteditingfontmatcher
[ui customization]: /guides/web/user-interface/ui-customization/introduction/

Discover Nutrient Web SDK 1.6 updates, including API improvements, annotation fixes, performance gains, and migration notes for upgrades.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.5 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-5/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-5/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Release notes for Nutrient Web SDK 1.5 highlighting new capabilities, API refinements, viewer/UI updates, and upgrade guidance.]]></description>
            <content:encoded><![CDATA[### UI updates

This release brings exciting improvements to the Web SDK’s user interface and theming system, making it more flexible and consistent. The following UI sections have been migrated in 1.5:

- Multi-select toolbar
- Signatures sidebar
- Print dialog
- Form Creator popover
- Loading screen

Most customizations will continue to work as before, but if you notice anything unexpected and you were using CSS classes or CSS variables for customization, our Baseline UI migration guide offers helpful tips and guidance.

### RTL layout and advanced theming

This release introduces RTL (Arabic/Hebrew) layout support. This feature represents an important step in our internationalization support. Reach out to us with feedback to help shape the future development of this feature.

Version 1.5 also delivers a major enhancement to theming with support for granular theme customization. Developers now have unprecedented control over the visual appearance of the SDK, allowing for more seamless integration with existing applications and brand identities. For example, you can now customize specific UI elements independently, creating a more cohesive look and feel that matches your application’s design language.

Additionally, we’ve added support for light and dark high contrast themes, significantly improving accessibility for users with visual impairments. These specialized themes enhance visibility and readability for users who require higher contrast ratios, ensuring the SDK is usable by a wider audience.

### Accessibility enhancements

Nutrient Web SDK 1.5 brings substantial improvements to accessibility. Accessibility labels and translations for toolbars have been enhanced, providing a better experience for screen reader users. We’ve also fixed several issues that affected keyboard navigation and screen reader compatibility:

- Resolved an issue where elements referenced in `aria-labelledby` and `aria-describedby` attributes weren’t present in the DOM. This improvement enhances compatibility with automated testing tools and improves the experience for screen reader users. List items in the annotation sidebar now correctly reference existing DOM elements.
- Fixed pagination buttons that lost aria attributes while using keyboard navigation. The “Previous Page” and “Next Page” buttons in the viewer toolbar now maintain their `role` and `aria-label` attributes when users navigate with the <kbd>Tab</kbd> key, ensuring consistent accessibility across interaction methods.

### Enhanced annotation capabilities

Version 1.5 brings significant refinements to the annotation experience, with a focus on color handling, mobile usability, and user interface consistency.

#### Improved color handling

The text color palette in annotations has been improved with a streamlined color selection interface. The transparent swatch option has been removed, creating a more intuitive color selection experience with only functional color options available. This refinement ensures that all available color choices behave consistently and predictably.

Additionally, we’ve enhanced the 'None' color selection functionality for font and background colors when working with multiple text selections. The 'None' option can now be selected even if it’s currently active, and color selections are consistently applied across all selected text, ensuring uniform behavior across all annotation types.

#### Enhanced mobile experience

We’ve fixed an issue where the comment drawer didn’t open properly on mobile devices. This fix ensures comments are now accessible across all device types and screen sizes, allowing users to seamlessly interact with comment marker annotations in mobile view.

#### User interface refinements

We’ve fixed an issue where layout configuration icons didn’t update when custom icons were passed via API. This fix allows developers to maintain a consistent visual language throughout their applications by ensuring custom icons are properly displayed.

We’ve also fixed an issue where users were able to submit blank typed signatures: The “Done” button is now disabled until at least one visible character is entered, ensuring signatures contain meaningful content and preventing potential errors.

Additionally, we’ve addressed a problem where the Document Editor image gallery didn’t auto-scroll during drag operations. This fix restores the ability to drag pages beyond the visible viewport during page reordering. For example, when reordering pages in a multipage document, the editor now automatically scrolls when a dragged page reaches the edge of the visible area.

### Core functionality and document handling

This release delivers substantial improvements to the core functionality of the SDK, with a focus on comments, document comparison, security, and rendering accuracy.

#### Comments UI

Previously, comments threads were always displayed in a floating sidebar to the side of the page, which wasn’t convenient as soon as the page was zoomed in and there wasn’t enough space left to show the comments without having to scroll the viewport. In this release, the comments sidebar is now only shown when there’s enough space to display it without scrolling. If there isn’t enough space, the comments are shown in a popover instead, which can be opened by clicking on the comment marker. This popover dialog was previously visible only in `FIT_TO_WIDTH` zoom mode.

We understand that this change may not be ideal for all use cases, so we now provide an extension to the `NutrientViewer.ViewState` API that makes it possible to customize this behavior at any time by setting `NutrientViewer.ViewState#commentDisplay`:

- `NutrientViewer.CommentDisplay.FITTING` — The default value; will show comments in a floating sidebar by the page side when there’s enough space to do so, and in a popover when there isn’t, and the marker annotation is selected.
- `NutrientViewer.CommentDisplay.FLOATING` — Will always show comments in a floating sidebar by the page side.
- `NutrientViewer.CommentDisplay.POPOVER` — Will always show comments in a popover when the marker annotation is selected.

As an example of how it’s used, here’s how to set the `commentDisplay` so the comments UI behaves like in previous versions, always showing comments in a floating sidebar unless in `FIT_TO_WIDTH` zoom mode:

```js
const instance = await NutrientViewer.load(config);

instance.setViewState((viewState) =>
  viewState.set("commentDisplay", NutrientViewer.CommentDisplay.FLOATING),
);

instance.addEventListener(
  "viewState.change",
  function (viewState, previousViewState) {
    const zoom =
      typeof viewState.zoom === "object"
        ? viewState.zoom.zoomMode
        : viewState.zoom;
    const previousZoom =
      typeof previousViewState.zoom === "object"
        ? previousViewState.zoom.zoomMode
        : previousViewState.zoom;

    if (
      previousZoom === zoom &&
      viewState.commentDisplay === previousViewState.commentDisplay
    ) {
      return;
    }

    if (
      zoom === NutrientViewer.ZoomMode.FIT_TO_WIDTH &&
      viewState.commentDisplay !== NutrientViewer.CommentDisplay.POPOVER
    ) {
      instance.setViewState((viewState) =>
        viewState.set("commentDisplay", NutrientViewer.CommentDisplay.POPOVER),
      );
    } else if (
      viewState.commentDisplay !== NutrientViewer.CommentDisplay.FLOATING
    ) {
      instance.setViewState((viewState) =>
        viewState.set("commentDisplay", NutrientViewer.CommentDisplay.FLOATING),
      );
    }
  },
);
```

#### Enhanced document comparison and XFDF support

Word-level text comparison has been added, providing more granular document comparison capabilities that allow users to identify changes with greater precision. Previously, all comparisons were done at the character level, which could result in unintuitive highlighting of changes. For example, changing “January” to “February” would show as a deletion of “Jan,” addition of “Febr,” and “uary” as unchanged. With word-level comparison, the entire word is highlighted as changed, creating a more intuitive and readable comparison.

Configuration options for rich text when working with XFDF files have also been added, expanding the SDK’s flexibility when working with this format and ensuring consistent rich text handling across different document workflows. This enhancement allows for better propagation of rich text configuration from the Web SDK to Core and Document Engine backends when performing XFDF operations.

#### Security and performance improvements

The Content Security Policy (CSP) HTTP header required `unsafe-eval` to be set in recent versions. You may now use `wasm-unsafe-eval` instead.

We’ve also updated GdPicture to version 14.3.9, bringing the latest improvements from this underlying technology to our SDK.

#### Rendering and UI consistency

Several rendering issues have been addressed to ensure accurate display of annotations and content:

- Fixed an issue where text markup annotations were rendered with the wrong proportions when zoomed, and in the wrong direction on rotated pages. This fix ensures markup annotations like squiggly, strikethrough, and underline now maintain appropriate proportions regardless of zoom level, page rotation, or text size, improving overall readability.
- Fixed an issue where moving a stamp annotation rotated at 45 degrees would resize it. This fix ensures stable dimensions for rotated stamps throughout all user interactions, preventing unwanted size changes during movement.
- Fixed an issue where comment threads would appear clipped in narrow screen widths. This fix ensures comment boxes now remain fully visible and accessible, even when the viewport is narrow or when using high zoom levels.
- Fixed an issue where the comments sidebar and popover were simultaneously visible in `FIT_TO_WIDTH` view mode. This fix creates a more consistent and less cluttered user interface.

#### Form handling and stability

- Fixed an issue where it wasn’t possible to correctly set the time in some time form fields. This fix ensures users can now properly set time values across all platforms, with consistent validation behavior and support for proper time formats on both desktop and mobile devices.
- Fixed an issue where using some Form Creator and Measurements dropdowns would throw an error. This fix resolves problems with Shadow DOM compatibility, ensuring consistent behavior when creating and managing form fields and annotations.
- Fixed an issue where the first new comment text field wouldn’t be focused when creating a comment, improving workflow efficiency. Additionally, we’ve fixed a crash that could occur when creating a text parser for a page with verbose logging enabled, ensuring consistent performance, even with complex document structures.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.4 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /changelog/web/#1.5.0
[web sdk 1.4 release notes]: /guides/web/release-notes/1-4/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[bui-migration]: /guides/web/migration-guides/baseline-ui-migration-guide/

Release notes for Nutrient Web SDK 1.5 highlighting new capabilities, API refinements, viewer/UI updates, and upgrade guidance.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.4 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-4/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-4/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Nutrient Web SDK 1.4 release notes with feature additions, bug fixes, performance boosts, and deprecations to address when upgrading.]]></description>
            <content:encoded><![CDATA[### UI and accessibility improvements

This release enhances keyboard accessibility with support for creating and editing note annotations using keyboard controls. Focus management and keyboard navigation of the annotation inline toolbar have also been improved, making the SDK more accessible to all users.

A notable correction addresses an issue where scrolling to a mouse position would change the zoom level, even when the mouse was outside the viewer. This fix provides a more predictable and controlled zooming experience.

### Enhanced annotation capabilities

Version 1.4 introduces several improvements to annotation functionality:

- A new configuration option, `TEXT_ANNOTATION_AUTOFIT_ON_BOTTOM_KNOB_RESIZE`, enables you to control whether font size should automatically adjust when resizing text annotations with the bottom-right handle.
- The functionality to resize text annotations by dragging the bottom-right handle has been improved, and it now supports rich text annotations with multiple font sizes.
- Text annotation presets now properly handle font size, font family, and font underline property selections between annotation creations.
- An issue where pasted annotations retained the same name as the original annotation has been fixed.

### Document rendering and text handling improvements

Font embedding behavior has been enhanced, resulting in fonts being embedded more often, and providing a better experience when documents are viewed in external viewers.

Line height calculation for plain text annotations has been improved, and carriage line breaks are now properly respected during import and export of text annotations.

The text comparison feature has been refined to correctly highlight changes involving multiple lines and to catch changes that might have been missed in previous versions.

### Additional enhancements

- A new configuration option for the attachment sidebar allows disabling attachment preview.
- A content editing API has been added, expanding the SDK’s capabilities.
- Thumbnail behavior has been improved to properly adjust size and position when the sidebar width changes.
- Various issues with form fields, linearized documents, and CA certificate recognition have been addressed.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.3 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /changelog/web/#1.4.0
[web sdk 1.3 release notes]: /guides/web/release-notes/1-3/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility

Nutrient Web SDK 1.4 release notes with feature additions, bug fixes, performance boosts, and deprecations to address when upgrading.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.3 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-3/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-3/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore Nutrient Web SDK 1.3 changes, including new APIs, stability fixes, rendering improvements, and steps for upgrading existing apps.]]></description>
            <content:encoded><![CDATA[### AI text comparison

This release introduces AI-powered text comparison, a major enhancement to the SDK’s existing comparison capabilities. By leveraging artificial intelligence, the new feature summarizes document differences, categorizes changes, and enables users to filter by high-level concepts like formatting, rewording, or content additions. Developers can enable AI comparison through a simple configuration using the AI Assistant service. For setup instructions and usage details, refer to the AI text comparison guide.

### Smarter annotation tools and UI enhancements

Version 1.3 brings more control over how annotations behave and appear across devices. Developers can now define a custom breakpoint for the annotation toolbar, tailoring the UI to different screen sizes and use cases. Callout annotations are more predictable and stable when zooming, thanks to a unified scaling system that keeps arrow placement consistent.

The text editing experience has also been refined. Font size and font family selections are now correctly saved when editing presets, and underline is now supported as part of the text style configuration. Manual entry of font sizes in Content Editor has also been improved to handle focus behavior more predictably.

We’ve resolved issues that could cause text annotations to become unresponsive when switching between them while in edit mode, and we fixed edge cases where line breaks in multiline callout annotations were removed, causing content to shift or disappear after saving. Additionally, annotations with special characters like angle brackets (<>) now render as expected, and annotation tool states (e.g. selected or disabled) reflect correctly in the UI.

### Improved accessibility and metadata handling

Nutrient Web SDK 1.3 brings better support for preserving accessibility-related metadata. `PDF/UA` tags are now retained when documents are edited, ensuring compliance with accessibility standards. The primary document language is also preserved, allowing assistive technologies to accurately interpret and present content. Alert and confirm dialogs are now properly centered, and focus is automatically directed to dialog buttons, improving keyboard accessibility.

### Expanded rendering and scripting capabilities

This release adds support for several advanced features in the PDF JavaScript API, including `AFTime_KeystrokeEx`, the JavaScript `global` object, and page-level open and close actions. These additions enable more dynamic, form-driven documents with behavior that closely matches native PDF viewers.

When converting Excel documents, developers can now specify maximum spreadsheet dimensions, and tile size is configurable for rendering optimization. We’ve also introduced a more resilient rendering path for callout and free text annotations to ensure appearance streams fit within annotation bounds.

Loading speeds for Office documents have been improved, and launching Content Editor on pages with dense vector graphics (such as architectural plans) is now more responsive.

### Behavioral changes

The `GoToAction` behavior has changed: It now sets destinations based on page references instead of page indexes. This means links will remain accurate, even if pages are moved or removed in the document editor.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

### Breaking changes

**PDF ID encoding correction**

This release includes a fix to how PDF trailer IDs are encoded in the `pdfId` field of Instant JSON. Previously, the encoding was incorrectly truncated, resulting in shorter `pdfId` values. The corrected behavior now properly encodes the complete PDF ID.

**Impact:** If you have existing Instant JSON files created with SDK versions prior to 1.3.0, they’ll contain `pdfId` values that won’t match when loading the same PDF in version 1.3.0 or later. This will result in a “Permanent PDF ID mismatch“ error.

**Migration options**

1. **Remove pdfId validation** (recommended for most cases) — Strip the `pdfId` property from existing Instant JSON:
   ```javascript
   const { pdfId, ...jsonWithoutPdfId } = existingInstantJSON;
   
   NutrientViewer.load({
     instantJSON: jsonWithoutPdfId,
   });
   ```
2. **Update existing Instant JSON** — Reexport your Instant JSON files using version 1.3.0 or later to generate corrected `pdfId` values.

{% alert line="single-line" %}
Removing `pdfId` is safe if your application ensures the correct PDF is loaded with its corresponding Instant JSON.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.2 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /guides/web/changelog/#1.3.0
[web sdk 1.2 release notes]: /guides/web/release-notes/1-2/
[ai text comparison guide]: /guides/web/comparison/compare-text-ai/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility

Explore Nutrient Web SDK 1.3 changes, including new APIs, stability fixes, rendering improvements, and steps for upgrading existing apps.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.2 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-2/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-2/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Nutrient Web SDK 1.2 release notes detailing new features, annotation and UI updates, performance tuning, and migration considerations.]]></description>
            <content:encoded><![CDATA[### DWS Viewer API support

This version of Nutrient Web SDK ships with support for opening documents from DWS Viewer API.

DWS Viewer API is a cloud-based deployment option that allows you to render PDFs, Office files, and images securely in the browser with all the benefits of backend processing that were previously only possible with an on-premises Document Engine deployment.

DWS Viewer API is now in public preview and ready for you to build with today. Start for free by signing up on the DWS Viewer API dashboard.

### Breaking API changes

The `NutrientViewer.ViewState#enableAlwaysScrollToZoom` property is being deleted in favor of the more flexible `ViewState.zoom` API. This change improves control over zoom behavior and aligns with our modern API design principles.

With this version, the property is removed completely and any code using it will stop working.

Before:

```js
instance.setViewState((viewState) =>
  viewState.set("enableAlwaysScrollToZoom", true)
);
```

After:

```js
// Always zoom on scroll wheel without requiring the Control key to be pressed.
instance.setViewState(
  new NutrientViewer.ViewState({
    zoom: {
      // Configure scroll wheel zoom behavior.
      wheelZoomMode: NutrientViewer.WheelZoomMode.ALWAYS
      // ... other zoom options
    }
  })
);
```

### Rich text annotations: Major enhancements

This release delivers significant improvements to rich text annotations, making them more reliable, consistent, and user-friendly.

Key enhancements

- Adds support for applying font size and font family to individual text segments, enabling more precise text styling.
- Standardizes behavior between background color and font color selections, ensuring consistent functionality across all color options.
- Synchronizes rich text properties with underlying annotation metadata when all text is selected, ensuring consistent display.
- Improves text formatting (bold, italic, underline) to work reliably during typing without disrupting line breaks or causing text to become hidden.
- Enhances color management to maintain focus when changing colors, with proper updating of color swatches and consistent color application.
- Preserves formatting and prevents data loss in multi-line text annotations during editing, deletion, and focus changes.
- Maintains styling and formatting when pasting rich text content, with proper placement of pasted text.
- Ensures consistent resizing behavior across all handles while preserving an annotation’s size, formatting, and alignment.
- Improves keyboard focus management and restoration in the toolbar for consistent behavior across browsers.
- Enhances AP stream generation with proper preservation of newlines and text formatting for improved document compatibility.

Nutrient Web SDK 1.2 release notes detailing new features, annotation and UI updates, performance tuning, and migration considerations.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.1 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-1/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-1/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[See what’s new in Nutrient Web SDK 1.1 with API enhancements, bug fixes, viewer improvements, and notes to help you upgrade safely.]]></description>
            <content:encoded><![CDATA[### New API: NutrientViewer.build()

`NutrientViewer.build()` performs processing via the Nutrient backend Build API.

Example usage:

```js
NutrientViewer.build(
  // Authorize request.
  { jwt: authPayload.jwt },
  // Instructions for the processing request.
  {
    parts: [
      // Use first input as the first part of the final document.
      { file: "document" },
      // Use a sample DOCX document served from a URL as the second part of the final document.
      {
        file: {
          url:
            "https://www.nutrient.io/api/assets/downloads/samples/docx/document.docx"
        }
      }
    ]
  },
  // Inputs required by the request. These will be uploaded with the request. The remote file served from URL does not need to be uploaded.
  [{ name: "document", content: document }]
);
```

### Performance and UX improvements

- Enhanced memory efficiency when decoding large documents, enabling better handling of resource-intensive PDFs.
- Improved UX when selecting text from right to left, particularly with sentence-ending words.
- Callout annotation text overflow, bounding box, and arrow positioning improvements.
- Updated key dependencies: React (18.3.1) and react-intl (7.1.6).

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For previous release notes, refer to the Web SDK 1.0 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /changelog/web/#1.1.0
[`nutrientviewer.build()`]: /api/web/functions/NutrientViewer.build.html
[build api]: /api/reference/public/#tag/Build-API
[web sdk 1.0 release notes]: /guides/web/release-notes/1-0/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility

See what’s new in Nutrient Web SDK 1.1 with API enhancements, bug fixes, viewer improvements, and notes to help you upgrade safely.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.0 release notes]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/1-0/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/1-0/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Release notes for Nutrient Web SDK 1.0 covering the rebrand, new npm package, API changes, performance fixes, and upgrade guidance.]]></description>
            <content:encoded><![CDATA[The legacy `pspdfkit` NPM package is now deprecated. Switch to the new `@nutrient-sdk/viewer` package by updating your application’s `package.json` file:

```bash
npm uninstall pspdfkit
npm install @nutrient-sdk/viewer
```

Beyond the renaming, 1.0.0 ships with numerous fixes, performance enhancements, and UI improvements. Refer to the changelog for full details.

Below, we highlight important changes you may need to address when upgrading, including several API updates and deprecations.

### Breaking API changes

The `NutrientViewer.ViewState#enableAlwaysScrollToZoom` property is deprecated in favor of the more flexible `ViewState.zoom API`. This improves zoom behavior control and aligns with our modern API design.

#### Current behavior

Existing implementations using `enableAlwaysScrollToZoom` will continue to work in 1.0.0 but will log warnings in the console.

#### Future behavior

In 2.0.0, `enableAlwaysScrollToZoom` will be removed entirely. Any code referencing it must be updated to use the new zoom API.

Before:

```js
instance.setViewState((viewState) =>
  viewState.set("enableAlwaysScrollToZoom", true),
);
```

After:

```js
instance.setViewState((viewState) =>
  viewState.set("zoom", {
    // Configure scroll wheel zoom behavior.
    wheelZoomMode: NutrientViewer.WheelZoomMode.ALWAYS,
    // ... other zoom options.
  }),
);
```

### UI updates

This release introduces a major update to the Web SDK’s user interface, with the following UI sections migrated:

- Link annotation toolbar
- Image and signature annotation (image) toolbar
- Stamp annotation toolbar
- Text highlight and markup annotation toolbar
- Content editor toolbar
- Form creator toolbar
- Ink eraser toolbar
- Note annotation toolbar
- Redaction toolbar
- Shape annotation toolbars
- Document crop toolbar

Most customizations will continue to work as before, but if you notice anything unexpected and you were using CSS classes or CSS variables for customization, our Baseline UI migration guide offers helpful tips and guidance.

### Toolbars UI migration

Annotation toolbars have undergone a significant overhaul to improve accessibility and customization capabilities, leveraging our in-house Baseline UI design system. These changes bring them in line with the updated look of other UI components, such as the sidebar and main toolbar, while also enhancing support for users’ accessibility requirements.

### Text Comparison API changes

Several updates have been made to the Text Comparison API to ensure consistency with documentation and to unify data handling.

1. `TextBlock.rects` renamed to `TextBlock.rect`

   **Previous behavior:** `TextBlock.rects` was documented, but no rects were returned.
   **Impact:** Use `TextBlock.rect` instead of `TextBlock.rects`.

2. `TextBlock.rect` coordinates format updated

   **Previous behavior:** Coordinates were returned using a PDF coordinate system.
   **Impact:** If your application relied on PDF-style coordinates, update your logic to accommodate the new `x`, `y`, `width`, `height` format.

3. `Operation.originalTextBlocks` and `Operation.changedTextBlocks` return arrays

   **Previous behavior:** Only one `TextBlock` object was documented to be returned.
   **Impact:** These now return an array of `TextBlock` objects. Make sure your code handles multiple items.

4. `PageComparisonResult.originalPageIndex` and `PageComparisonResult.changedPageIndex` are optional

   **Previous behavior:** These properties were always present.
   **Impact:** Your code should now handle the possibility that these values may be undefined — particularly when comparing documents with differing page counts.

### Signing document hashes via DWS Processor API and Document Engine

This release adds a new signing API, which enables direct hash signing with Document Engine and DWS Processor API when Web SDK operates client-side in the browser. An access token just needs to be passed to the `signDocument` method. Learn more in our guides on how to sign via DWS Processor API and how to sign via Document Engine.

### Attachments sidebar and preview

A new attachments sidebar has been added. It displays a list of all files embedded in a PDF, and users can preview these files directly in the viewer or download them if the file format is unsupported. Previewing files is unavailable when using Document Engine — in this case, files can only be downloaded.

{% alert line="multi-line" %}
Document Engine 1.5.6 or later is compatible with this release. See the Web SDK and Document Engine compatibility requirements.
{% /alert %}

For a complete list of changes, bug fixes, and performance improvements, refer to the changelog. For the previous release notes, see Web SDK 2024.7 release notes. We appreciate your feedback and contributions as we continue to enhance Nutrient Web SDK.

[changelog]: /changelog/web/#1.0.0
[`nutrientviewer.viewstate#enablealwaysscrolltozoom`]: /api/web/classes/NutrientViewer.Instance.html#enablealwaysscrolltozoom
[`viewstate.zoom api`]: /api/web/classes/NutrientViewer.ViewState.html#zoom
[web sdk 2024.7 release notes]: /guides/web/release-notes/2024-7/
[dws sign]: /guides/web/signatures/digital-signatures/signature-lifecycle/sign-a-pdf-document-dws/
[de sign]: /guides/web/signatures/digital-signatures/signature-lifecycle/sign-a-pdf-document-document-engine/
[web sdk and document engine compatibility requirements]: /guides/document-engine/viewer/client-integration/web/#version-compatibility
[bui-migration]: /guides/web/migration-guides/baseline-ui-migration-guide/

Release notes for Nutrient Web SDK 1.0 covering the rebrand, new npm package, API changes, performance fixes, and upgrade guidance.]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Upgrading Nutrient Web SDK]]></title>
            <link>https://www.nutrient.io/guides/web/release-notes/upgrading/</link>
            <guid isPermaLink="false">https://www.nutrient.io/guides/web/release-notes/upgrading/</guid>
            <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Find upgrade guidance for Nutrient Web SDK releases, including links to versioned notes, Document Engine changes, and operational modes.]]></description>
            <content:encoded><![CDATA[Web SDK can be used together with Document Engine, which allows offloading document operations from the browser. Refer to the Document Engine changelog for more information.

Learn more about the available operational modes.

[document engine]: /guides/document-engine/
[document engine changelog]: /guides/document-engine/about/changelog/
[operational modes]: /guides/web/about/operational-modes/

Find upgrade guidance for Nutrient Web SDK releases, including links to versioned notes, Document Engine changes, and operational modes.]]></content:encoded>
        </item>
    </channel>
</rss>