Hierarchy
Properties
aiAssistant
Example
NutrientViewer.load({
aiAssistant: {
sessionId: 'session-id',
jwt: 'xxx.xxx.xxx',
backendUrl: 'https://localhost:4000',
},
// ...
});
allowLinearizedLoading
Standalone only
Enables or disables loading of linearized PDFs. When enabled, the SDK takes advantage of linearized (also known as "fast web view") PDFs, allowing portions of the document to be displayed while it's still being downloaded. If enabled, the PDF viewer will render the document progressively, starting with the first pages, while the rest of the file is downloaded in the background. The user interface will be in read-only mode during the download.
A indicator is displayed in the toolbar showing that the document is being downloaded.
Note: Linearized loading requires the server to support byte-range requests and the PDF document to be linearized.
Example
NutrientViewer.load({
allowLinearizedLoading: true,
// ...
});
Default Value
trueannotationPresets
This property allows you to change a default list of annotation presets for the NutrientViewer instance. This can be used to customize the main toolbar buttons' behaviour before the application mounts.
When omitted, it will default to NutrientViewer.defaultAnnotationPresets.
Example
const annotationPresets = NutrientViewer.defaultAnnotationPresets
annotationPresets.mypreset = {
strokeWidth: 10,
};
NutrientViewer.load({
...baseOptions,
annotationPresets,
});
Default Value
Sets a custom comparator that controls the visual rendering order of non-interactive annotations on each page. When set, this comparator replaces the SDK's default type-based rendering order for annotations such as text markups, ink, images, shapes, and stamps.
Interactive annotations — widget annotations (form fields), link annotations, and signature annotations — are always rendered above all other annotations regardless of the comparator, to preserve keyboard tab order and accessibility.
The comparator receives two annotations and must return -1 if the first
annotation should render below (behind) the second, or 1 if it should
render above (in front of) the second. A strict total order is required.
This can also be set at runtime via NutrientViewer.Instance#setAnnotationRenderingOrderComparator.
Limitations:
- Widget, link, and signature annotations always render on top.
- It does not change the keyboard tab order. Hit testing follows the visual stacking the comparator produces (topmost annotation receives events first).
- It does not affect annotation order in exported PDFs or backend storage.
Example
NutrientViewer.load({
annotationRenderingOrderComparator: (a, b) => {
const isImageA = a instanceof NutrientViewer.Annotations.ImageAnnotation;
const isImageB = b instanceof NutrientViewer.Annotations.ImageAnnotation;
if (isImageA !== isImageB) return isImageA ? -1 : 1;
if (a.createdAt < b.createdAt) return -1;
if (a.createdAt > b.createdAt) return 1;
return a.id < b.id ? -1 : 1;
},
});
annotationToolbarColorPresets
You can customize the color dropdown of individual annotation properties using this callback. This callback receives the property name associated with the color dropdown and the array of default colors used by NutrientViewer.
With this API you can:
- render a customised color pallet in each and all color dropdowns
- control if the custom color picker UI should be rendered in the color dropdowns
Example
Customize different color dropdowns.
NutrientViewer.load({
annotationToolbarColorPresets: function ({ propertyName }) {
if (propertyName === "font-color") {
return {
presets: [
{
color: new NutrientViewer.Color({ r: 0, g: 0, b: 0 }),
localization: {
id: "brightRed",
defaultMessage: "Bright Red",
},
},
{
color: new NutrientViewer.Color({ r: 100, g: 100, b: 180 }),
localization: {
id: "deepBlue",
defaultMessage: "deepBlue",
},
},
],
};
}
if (propertyName === "stroke-color") {
return {
presets: [
{
color: new NutrientViewer.Color({ r: 0, g: 0, b: 0 }),
localization: {
id: "brightRed",
defaultMessage: "Bright Red",
},
},
{
color: new NutrientViewer.Color({ r: 100, g: 100, b: 180 }),
localization: {
id: "deepBlue",
defaultMessage: "deepBlue",
},
},
],
showColorPicker: false,
};
}
},
//...
});
annotationToolbarItems
You can customise the items inside the annotation toolbars by using this callback. The callback will receive the annotation which is being created or selected and based on it, you can have different annotation toolbars for different annotations.
You can do the following modifications using this API:
- Add new annotation toolbar items
- Remove existing annotation toolbar items
- Change the order of the existing annotation toolbar items
- Modify selected properties of the annotation toolbar items
You can also use the hasDesktopLayout to determine if the current UI is being rendered on
mobile or desktop layout mode, which depends on the current viewport width. Based on that,
you can implement different designs for Desktop and Mobile.
This callback gets called every time the annotation toolbar is mounted.
Example
Add a new annotation toolbar item
NutrientViewer.load({
annotationToolbarItems: (annotation, { defaultAnnotationToolbarItems, hasDesktopLayout }) => {
const node = document.createElement('node')
node.innerText = "Custom Item"
const icon = `<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" /></svg>`
return [{
id: "custom",
type: "custom",
node: node,
icon: icon,
className: 'Custom-Node',
onPress: () => alert("Custom item pressed!")
}, ...defaultAnnotationToolbarItems];
}
});
annotationTooltipCallback
This callback is called whenever an annotation gets selected and can be used to define and return an array of ToolItem that will be rendered in a tooltip for the given annotation.
If the callback returns an empty array then NutrientViewer won't show any tooltip for the selected annotation.
Example
NutrientViewer.load({
annotationTooltipCallback: function(annotation) {
if (annotation instanceof NutrientViewer.Annotations.TextAnnotation) {
var toolItem = {
type: 'custom',
title: 'tooltip item for text annotations',
id: 'item-text-tooltip-annotation',
className: 'TooltipItem-Text',
onPress: function () {
console.log(annotation)
}
}
return [toolItem]
} else {
return []
}
}
// ...
});
appName
When integrating NutrientViewer for Electron with context isolation enabled, this property needs to be set for the SDK to work. It will be ignored in any other case.
The value of this property needs to match the provided license key's bundle ID.
Example
NutrientViewer.load({ appName: "my-electron-app" })
autoCloseThreshold
Threshold in pixels determines when the active anchor should automatically close and snap to the origin anchor, effectively closing the shape.
Example
NutrientViewer.load({
autoCloseThreshold: 50,
});
Default Value
4pxautoSaveMode
This property allows you to set the auto save mode, which controls when annotations or form field values get saved.
The default is IMMEDIATE when Instant is enabled, and INTELLIGENT otherwise.
On server-backed loads, Instant is enabled by instant: true, and by default when
authenticating with a session without a document.
Example
NutrientViewer.load({ autoSaveMode: NutrientViewer.AutoSaveMode.INTELLIGENT })
baseCoreUrl
This allows you to overwrite the auto-detected URL for the Core worker NutrientViewer assets in Standalone mode. This setting may be necessary when you integrate Nutrient Web SDK in an environment that limits the size of the static assets, like Salesforce.
If your Core assets are served from a different origin, you have to include proper CORS headers: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
This must end with a trailing slash, and the Core assets (nutrient-viewer-[hash].wasm.js
and nutrient-[hash].wasm) must be located in a nutrient-viewer-lib subfolder accessible
from the baseCoreUrl.
Example
NutrientViewer.load({ baseCoreUrl: 'https://public-server.pspdfkit.com/pspdfkit-core/' });
Default Value
Auto-detected it will use the same value as baseUrl if set, or the auto-detected value
from the currently executed <script> tag.
baseProcessorEngineUrl
optional, Standalone only
This allows you to overwrite the auto-detected URL for the processor engine worker NutrientViewer assets in Standalone mode. This setting may be necessary when you integrate Nutrient Web SDK in an environment that limits the size of the static assets, like Salesforce.
If these assets are served from a different origin, you have to include proper CORS headers: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
This must end with a trailing slash, and the assets in the /nutrient-viewer-lib/gdpicture-[hash]/ folder must be directly located
in the folder pointed to by baseProcessorEngineUrl.
Example
NutrientViewer.load({ baseProcessorEngineUrl: 'https://public-cdn.example.com/pspdfkit-processor-engine/' });
Default Value
Auto-detected it will use the same value as baseUrl if set, or the auto-detected value
from the currently executed <script> tag.
baseUrl
This allows you to overwrite the auto-detected URL for all NutrientViewer assets. This setting is necessary when you load Nutrient Web SDK JavaScript from a different URL.
If your assets are served from a different origin, you have to include proper CORS headers: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Example
NutrientViewer.load({ baseUrl: 'https://public-server.pspdfkit.com/' });
Default Value
Auto-detected based on the currently executed <script> tag.
Note: auto-detection behavior is deprecated as of 1.9.0. Not providing baseUrl will currently trigger a warning and in future releases will lead to loading assets from CDN.
blackRendering
Controls how exact 100% K-only CMYK black is rendered.
This option matters for print-production documents that use CMYK color:
by default, 100% K black is rendered as a dark charcoal, matching how
Acrobat displays it on screen. Pure black rendering maps it to #000000
instead, which some print workflows prefer for checking black-only
content. Documents that don't use CMYK color are unaffected.
In server-backed mode, this option requires Document Engine 1.18.0 or later and is ignored by older servers.
Example
NutrientViewer.load({
blackRendering: NutrientViewer.BlackRendering.PURE_BLACK,
// ...
});
Default Value
NutrientViewer.BlackRendering.ACCURATEcertificateCheckTime
optional, Standalone only
Determines the time used for certificate validation when verifying digital signatures.
'signing_time'(default): Validates certificates against the time when the document was signed. Recommended for Long Term Validation (LTV) scenarios where certificates may have short validity windows (e.g., GlobalSign certificates with 10-minute validity).'current_time': Validates certificates against the current system time.
Example
Use signing time for certificate validation
NutrientViewer.load({
certificateCheckTime: 'signing_time',
// ...
})
Default Value
'signing_time'
container
Selector or element where Nutrient Web SDK will be mounted.
Required unless headless: true is set.
The element must have a width and height that's greater than zero. Nutrient Web SDK adapts to the dimensions
of this element. This way, applying responsive rules will work as expected.
The element can be styled using relative values as you would expect it to (CSS media queries are encouraged).
Example
// In your HTML
<div class="foo"></div>
// In your JavaScript
NutrientViewer.load({
container: '.foo',
// Other configuration options
});
// or
const element = document.getElementsByClassName('foo')[0]
NutrientViewer.load({
container: element,
// Other configuration options
});
contentEditingFontMatcher
Callback function to handle font matching during content editing operations.
This callback is invoked when the system detects a font mismatch during content editing and allows you to provide custom font substitution logic. The callback receives the system's proposed font match and metadata about the original font from the PDF.
If the callback returns a font reference, it overrides the system's choice. If it returns
undefined, the system's original match is used.
Example
NutrientViewer.load({
contentEditingFontMatcher: (match, fontInfo, availableFonts) => {
console.log('System matched:', match);
console.log('Original font:', fontInfo.name, 'at', fontInfo.fontSize + 'px');
console.log('Available fonts:', availableFonts.map(f => f.family));
// For Helvetica fonts, try to find a suitable substitute
if (fontInfo.name?.includes("Helvetica")) {
// Look for Arial first, then any sans-serif font
const preferredFonts = ["Arial", "Roboto", "Open Sans", "Lato"];
for (const preferred of preferredFonts) {
const font = availableFonts.find(f => f.family.includes(preferred));
if (font) {
return { font, size: fontInfo.fontSize };
}
}
// Fallback to first available font
if (availableFonts.length > 0) {
return { font: availableFonts[0], size: fontInfo.fontSize };
}
}
return undefined; // Accept system match
}
});
customFonts
optional, Standalone only
This property allows you to provide custom fonts you want to use when loading a Standalone instance.
From the callback defined on each NutrientViewer.Font instance you can return a promise
that resolves to a Blob of the font you want to use. You are free to fetch it in whatever
way you want, and optimize its loading by retrieving it from a cache using the
Cache API, get it
from IndexedDB, etc.
See this guide article to learn more.
Example
Fetch and use a custom set of fonts (Standalone)
const fetcher = name =>
fetch(`https://example.com/${name}`).then(r => {
if (r.status === 200) {
return r.blob();
} else {
throw new Error();
}
});
const customFonts = ["arial.ttf", "helvetica.ttf", "tahoma.ttf"]
.map(font => new NutrientViewer.Font({ name: font, callback: fetcher }));
NutrientViewer.load({
customFonts,
// ...
});
customRenderers
This object can include functions to be called when specific entities, like annotations, are being rendered in the viewport, and return additional or replacement DOM content for the entity instance.
Currently only annotation's rendering can be customized using the Annotation key.
If the callback returns null, the instance will be rendered normally.
Example
NutrientViewer.load({
customRenderers: {
Annotation: ({ annotation }) => ({
node: document.createElement('div').appendChild(document.createTextNode('Custom rendered!')),
append: true,
})
}
// ...
});
customUI
Object with callback methods to be called when different elements of the UI are being rendered. Can return DOM content to be appended to them, as well as callback functions to individually process different parts of the element (items) as they're rendered.
UI elements currently supported: sidebars.
Example
//Fully customized sidebar
NutrientViewer.load({
customUI: {
[NutrientViewer.UIElement.Sidebar]: {
[NutrientViewer.SidebarMode.CUSTOM]({ containerNode }) {
// React portals can be used as well.
// Or Vue portals, or any other framework API that allows appending components
// to arbitrary DOM nodes.
// Using vanilla JS, you can just append a node to parentNode.
const div = document.createElement("div");
div.append("My custom sidebar");
containerNode.appendChild(div);
return {
// By returning the same node that was provided, we opt-out of having the node
// appended. If we return a different node, it will be appended to the provided node.
node: containerNode,
};
}
}
}
});
//Partially customized sidebar
NutrientViewer.load({
customUI: {
[NutrientViewer.UIElement.Sidebar]: {
[NutrientViewer.SidebarMode.ANNOTATIONS]({ containerNode }) {
containerNode.style.padding = "0.5rem";
if (!containerNode.querySelector(".MyCustomSidebarComponentHeader")) {
const header = document.createElement("div");
header.classList.add("MyCustomSidebarComponentHeader");
containerNode.prepend(header);
}
return {
node: containerNode,
onRenderItem({ itemContainerNode, item: annotation }) {
const footerAuthor = itemContainerNode.querySelector(".PSPDFKit-Sidebar-Annotations-Footer span");
// Change the format of the footer text by prefixing it with "Creator: " and removing the date
footerAuthor.textContent = `Creator: ${annotation.creatorName}`;
// Add aria label to the annotation icon
const annotationIcon = itemContainerNode.querySelector(".PSPDFKit-Icon");
annotationIcon.setAttribute("aria-label", `Icon for an annotation created by ${annotation.creatorName}.`);
}
};
}
}
}
});
dateTimeString
Allows you to customize how to format dates displayed in the UI.
When a date is about to be rendered in specific UI elements, this function is called so the date can be formatted as desired instead of using the default date formatter.
UI elements with customizable dates currently include the annotations sidebar, and comment threads.
This function is called for each date to be formatted, and receives the corresponding Date object, the UI element to which it belongs
(either the annotations sidebar or a comment thread) and the AnnotationsUnion or NutrientViewer.Comment instance
to which it is associated.
Example
NutrientViewer.load({
dateTimeString: ({ dateTime, element }) => {
if(element === NutrientViewer.UIDateTimeElement.ANNOTATIONS_SIDEBAR) {
return new Intl.DateTimeFormat("en-US", {
dateStyle: "short",
timeStyle: "short",
}).format(dateTime);
} else {
return new Intl.DateTimeFormat("en-US", {
dateStyle: "full",
timeStyle: "long",
}).format(dateTime);
}
}
// ...
});
Default Value
undefineddisableForms
This property is used to force the disabling of form rendering and parsing, even if your license would permit it.
Example
NutrientViewer.load({ disableForms: true })
Default Value
falsedisableHighQualityPrinting
Legacy flag for controlling DOM print quality.
Prefer printOptions.quality instead.
Example
NutrientViewer.load({ disableHighQualityPrinting: true })
Default Value
falsedisableIndexedDBCaching
disableMultiSelection
Disable multi selection for annotations. Disabled by default, when enabled it doesn't allow multiple selection of annotations by calling NutrientViewer.Instance.setSelectedAnnotations, or using the multiple annotations selection UI button.
Example
NutrientViewer.load({
disableMultiSelection: true,
});
Default Value
falsedisableOpenParameters
By default, Nutrient Web SDK will initialize using PDF Open Parameters that are supported by our viewer. This option can be used if you want to opt-out from this behavior.
Setting a custom ViewState will overwrite these defaults. You can use NutrientViewer.viewStateFromOpenParameters to manually extract those values.
Currently, we only support the page parameter.
Example
NutrientViewer.load({
disableOpenParameters: true,
});
disableTextSelection
When this property is set to true, text in the document can not be highlighted.
Example
NutrientViewer.load({ disableTextSelection: true })
disableWebAssemblyStreaming
Optional
When disableWebAssemblyStreaming is set to true, we force disable WebAssembly streaming
instantiation. More info about this optimization can be found at:
https://www.nutrient.io/blog/optimize-webassembly-startup-performance/
Example
NutrientViewer.load({
disableWebAssemblyStreaming: true,
// ...
});
document
required, Standalone only
The URL to a supported document or its content as ArrayBuffer.
NutrientViewer supports the following type of documents:
- Image
Note that all the formats except for PDF require a dedicated license. Please contact sales to find out more about this.
When providing a URL keep in mind that Cross-Origin Resource Sharing (CORS) apply.
To load app-provided documents with DWS Viewer API, see session.
Example
Load a PDF document from an URI
NutrientViewer.load({ document: 'https://example.com/document.pdf' });
Load a document from an ArrayBuffer
NutrientViewer.load({ document: arrayBuffer });
documentEditorConfiguration
{ … }
An object that allows you to configure the Document Editor UI.
| Property | Description |
|---|---|
| thumbnailDefaultSize | The default size of the thumbnail. |
| thumbnailMaxSize | The maximum size of the thumbnail. |
| thumbnailMinSize | The minimum size of the thumbnail. |
Example
NutrientViewer.load({
documentEditorConfiguration: {
thumbnailDefaultSize: 500,
thumbnailMinSize: 100,
thumbnailMaxSize: 600,
}
// Other configuration options
})
documentEditorToolbarItems
This property allows you to set an initial list of document editor toolbar items for the NutrientViewer instance.
When omitted, it will default to NutrientViewer.defaultDocumentEditorToolbarItems.
Example
const toolbarItems = NutrientViewer.defaultDocumentEditorToolbarItems;
toolbarItems.reverse();
NutrientViewer.load({
documentEditorToolbarItems: toolbarItems
// Other configuration options
});
Default Value
Errors
will throw an error when the supplied items array is not valid. This will also throw an error if your license does not include the Document Editor feature.
dynamicFonts
optional, Standalone only
This property allows you to provide a URL to JSON file with fonts available for downloading, associated with specific ranges of characters and font variations.
The downloadable font files need to be in the same scope as the JSON file.
The JSON file needs to be in the following format:
type FontName = {
// The full name of the font.
fullName: string;
// The next four properties are from the `name` table in the font.
// See https://learn.microsoft.com/en-us/typography/opentype/spec/name#name-ids
// Name ID 1: Font Family name
family?: string;
// Name ID 2: Font Subfamily name
subfamily?: string;
// Name ID 16: Typographic Family name
typographicFamily?: string;
// Name ID 17: Typographic Subfamily name
typographicSubfamily?: staring;
}
// Represents a font that can be downloaded.
// filePath + faceIndex should be unique.
type Font = {
name: FontName;
// Path to the font file.
filePath: string;
// If the font file is a collection, this specifies the face index.
faceIndex?: int;
// A list of all code points supported by the font.
// This can either be a range ([number, number]) or a single codepoint.
codePoints: [[number, number] | number];
// The unicode ranges from the OS/2 table: https://learn.microsoft.com/en-us/typography/opentype/spec/os2#ur
unicodeRanges?: [4 numbers];
// A sha1 of the font file. For collections, this is a SHA of the whole file, not a single font.
sha1: string;
// Specifies true if the font is allowed to be embedded, false otherwise.
// Should only be used to make a decision to download the font, proper licensing handling should be done with the downloaded font.
allowedToEmbed: boolean;
// The boldness of the font. See https://learn.microsoft.com/en-us/typography/opentype/spec/os2#wtc
weight?: number;
}
type DynamicFonts = {
availableFonts: [Font];
v: 1;
}
Example
Provide a list of downloadable font files (Standalone)
NutrientViewer.load({
dynamicFonts: "https://example.com/assets/fonts.json",
// ...
});
editableAnnotationTypes
This property defines all annotation types that a user is able to modify. If it's not set, the user is allowed to select, create, edit or delete every annotation type. By allowing only certain annotation types for modification, you can be sure that there is no annotation type that gets introduced in the future that your user is then able to modify.
Example
Allow only the modification of ink annotations
NutrientViewer.load({
editableAnnotationTypes: [NutrientViewer.Annotations.InkAnnotation],
// ...
});
electronAppName
When integrating NutrientViewer for Electron with context isolation enabled, this property needs to be set for the SDK to work. It will be ignored in any other case.
The value of this property needs to match the provided license key's bundle ID.
Deprecated
Use Configuration.appName and Configuration.productId instead.
Example
NutrientViewer.load({ electronAppName: "my-electron-app" })
electronicSignatures
Defines specific configuration options related to the electronic signatures feature.
The creationModes key accepts an array of NutrientViewer.ElectronicSignatureCreationMode values that
define which signature creation modes and in which order will be offered as part of the Electronic Signatures
UI. It defaults to NutrientViewer.defaultElectronicSignatureCreationModes.
The fonts key accepts an array of Font instances that specify the name of fonts to be used as part
of the 'Type' signing tab. It defaults to NutrientViewer.defaultSigningFonts.
You can specify a subset of our built-in signing fonts or specify entirely custom ones.
For using custom fonts, you need to load a custom style sheet (via Configuration#styleSheets)
in which you can either specify @font-face rules for the custom font or @import other style sheets containing the fonts loading rules.
As an example of the latter, if we would wish to use the Cookie font from Google Fonts you could use the following style sheet:
@import url('https://fonts.googleapis.com/css2?family=Cookie&display=swap');
And then pass an new NutrientViewer.Font({ name: 'Cookie' }) as part of the fonts array of
Configuration#electronicSignatures.
Example
NutrientViewer.load({
electronicSignatures: {
creationModes: [NutrientViewer.ElectronicSignatureCreationMode.IMAGE],
fonts: [new NutrientViewer.Font("Cookie")]
}
});
enableAutomaticLinkExtraction
Standalone only
By default, only links that are represented as valid link annotations in the PDF will be enabled.
When enableAutomaticLinkExtraction is set to true, the text of the PDF will be scanned and
links will automatically be created.
To enable automatic link extraction on a Nutrient Document Engine (server-backed) deployment, check out: https://www.nutrient.io/guides/web/pspdfkit-server/configuration/overview/
Example
NutrientViewer.load({
enableAutomaticLinkExtraction: true,
// ...
});
enableClipboardActions
Enable actions like cut, copy, paste and duplicate for annotations using keyboard shortcuts Cmd/Ctrl+X, Cmd/Ctrl+C, Cmd/Ctrl+V and Cmd/Ctrl+D respectively.
Example
NutrientViewer.load({
enableClipboardActions: true,
});
Default Value
falseenableHistory
Enable actions history for annotations. Disabled by default, when enabled it allows to undo and redo annotation actions consecutively by calling NutrientViewer.Instance#history.undo or NutrientViewer.Instance#history.redo, or using the undo and redo UI buttons, which can be optionally enabled:
Actions history tracking can be enabled and disabled at any moment by calling NutrientViewer.Instance#history.enable or NutrientViewer.Instance#history.disable.
Example
NutrientViewer.load({
enableHistory: true,
toolbarItems: NutrientViewer.defaultToolbarItems.reduce((acc, item) => {
if (item.type === "spacer") {
return acc.concat([item, { type: "undo" }, { type: "redo" }]);
}
return acc.concat([item]);
}, [])
});
Default Value
falseenableRichText
This call back defines which text annotations should be treated as rich text annotation.
By default, all the text annotations are treated as plain text annotations, which means that
when you edit them, you will see the plain text editor. You can change this behavior by
returning true for the text annotations that you want to be treated as rich text annotations.
Example
NutrientViewer.load({ enableRichText: annotation => true });
enableServiceWorkerSupport
When you're using a ServiceWorker, set this flag to true to be able to use Nutrient Web SDK
offline. Due to a browser bug, loading CSS files would bypass service workers and we therefore
load all CSS files via XHR and embed the content. Instead of loading files like SVGs by using
url in your CSS, please add them as base64, otherwise these requests would bypass the service
worker as well.
Example
NutrientViewer.load({
enableServiceWorkerSupport: true,
// ...
});
fontSubstitutions
Allows specifying fonts that you would like to substitute in a document and the fonts you would like to use for that substitution.
Patterns are matched using the following rules:
*matches multiple characters.?matches a single character.
Ordering matters - As names could match multiple patterns, it's important to note that the order of the patterns matters.
Case-insensitive - Both the pattern and the target name are case-insensitive.
Example
Substitute all Noto fonts found in the document with Awesome font
NutrientViewer.load({
fontSubstitutions: [
{
pattern: "Noto*",
target: "AwesomeFont"
}
]
});
formFieldsNotSavingSignatures
List of signature form fields names that are not allowed to store Ink Signatures.
When a signature form field name is on this list, any new ink signature for this field that is created via the UI won't be stored.
Example
NutrientViewer.load({
formFieldsNotSavingSignatures: ['signatureField1'],
// ...
});
Default Value
[]formsConfiguration
Standalone only
Allows configuring some behavior around forms in the viewer.
Example
NutrientViewer.load({
formsConfiguration: { },
});
Default Value
undefinedheadless
Loads Nutrient Web SDK in Headless mode i.e. without a UI. Some UI-specific APIs, like the Toolbars API, are not available in this mode and, when used, will throw an error.
Example
NutrientViewer.load({
headless: true,
// ...
});
httpHeaders
Standalone only
Custom HTTP headers to include when fetching the document from a URL.
This property is only used when document is a string URL (not an ArrayBuffer).
The headers will be applied to both the initial document fetch and any subsequent range requests when using linearized loading.
Example
NutrientViewer.load({
document: 'https://example.com/document.pdf',
httpHeaders: {
'Authorization': 'Bearer token123',
'X-Custom-Header': 'custom-value'
}
});
Default Value
undefinedinitialViewState
This property allows you to set an initial viewing state for the NutrientViewer instance.
This can be used to customize behavior before the application mounts (e.g Scroll to a specific page or use the SINGLE_PAGE mode)
It will default to a view state with its default properties (see ViewState).
If the initial view state is invalid (for example, when you define a page index that does not
exist), the method will fall back to the default value for the invalid property. This means when
you set the initial currentPageIndex to 5 but the document only has three pages, NutrientViewer will
start on the first page but will still apply other rules defined in this initial view state.
Example
const initialViewState = new NutrientViewer.ViewState({ currentPageIndex: 2 });
NutrientViewer.load({
initialViewState,
// Other configuration options
});
Default Value
inkEraserMode
Allows you to modify the default ink eraser behavior. By default, the eraser removes points from ink annotations.
Set this to InkEraserMode.STROKE to erase whole strokes instead.
Example
NutrientViewer.load({ inkEraserMode: NutrientViewer.InkEraserMode.STROKE });
Default Value
NutrientViewer.InkEraserMode.POINTinlineTextSelectionToolbarItems
You can customize the items inside the inline text selection toolbar that is rendered every time some text is selected on the document. The callback will receive the default items of the inline toolbar and the text that is currently selected NutrientViewer.TextSelection
You can do the following modifications using this API:
- Add new toolbar items
- Remove existing toolbar items
- Change the order of the existing annotation toolbar items
- Customise each item eg change the
iconof the a default toolbar item.
You can also use the hasDesktopLayout to determine if the current UI is being rendered on
mobile or desktop layout mode, which depends on the current viewport width. Based on that,
you can implement different designs for Desktop and Mobile.
This callback gets called every time the inline text selection toolbar is mounted.
Example
Add a custom button and a custom node to the toolbar in desktop layout.
NutrientViewer.load({
inlineTextSelectionToolbarItems: ({ defaultItems, hasDesktopLayout }, selection) => {
console.log(selection)
if (hasDesktopLayout) {
const node = document.createElement("div");
node.innerText = "Custom Item";
return [
...defaultItems,
{
type: "custom",
id: "custom-1",
node: node,
className: "Custom-Node",
onPress: () => alert("Custom node pressed!"),
},
{
type: "custom",
id: "custom-2",
title: "custom-button-2",
onPress: () => alert("Custom item pressed!"),
},
];
}
return defaultItems
},
})
inlineWorkers
By default, we load the required Web Workers inline. That means that the Web Workers are loaded as a
blob URL, which allows us to load a Worker from other domains. However, this might interfere with strict CSP policies like worker-src: 'self'.
In that case, disable inline loading by setting this option to false, serve or proxy the SDK assets
from the embedding application's origin, and configure baseUrl to that same-origin location.
This option governs the SDK's workers in both Standalone and Document Engine deployments, with one
exception: the OffscreenCanvas renderer worker used by the next page renderer
(pageRendering: "next") currently always loads inline.
Note: This option is currently not supported in Salesforce environment.
Example
NutrientViewer.load({
inlineWorkers: false,
// ...
});
Default Value
trueinstantJSON
Standalone only
Instant JSON can be used to instantiate a viewer with a diff that is applied to the raw PDF. This format can be used to store annotation changes on your server and conveniently instantiate the viewer with the same content at a later time.
Instead of storing the updated PDF, this serialization only contains a diff that is applied on top of the existing PDF and thus allows you to cache the PDF and avoid transferring a potentially large PDF all the time.
You can export this format from a standalone instance by using Instance#exportInstantJSON.
annotations will follow the Instant Annotation JSON format specification.
Example
NutrientViewer.load({
instantJSON: {
format: 'https://pspdfkit.com/instant-json/v1',
skippedPdfObjectIds: [1],
annotations: [
{ id: 1, pdfObjectId: 1, type: 'pspdfkit/text', content: 'Hello World' },
{ id: -1, type: 'pspdfkit/text', content: 'Hello Universe' },
],
},
// ...
});
isEditableAnnotation
By implementing this callback you have a fine grained control over which annotations are read-only.
This callback will receive the Annotation a user wants to modify and by returning true or
false you can define if the annotation should be read-only (false) or modifiable (true).
This API will not disable ToolbarButtons for you, but will not allow the user to create a new Annotation with the UI.
Example
Only allow the modification of annotations from the same author
NutrientViewer.load({
isEditableAnnotation: function(annotation) {
return annotation.creatorName === myCurrentUser.name;
},
});
Do not allow changing the value of a specific form field
NutrientViewer.load({
isEditableAnnotation: function(annotation) {
// Check if the annotation is associated with a specific form field
if (
annotation instanceof NutrientViewer.Annotations.WidgetAnnotation &&
annotation.formFieldName === "MyFormField"
) {
// If it is, disallow editing it
return false;
}
// Otherwise, allow editing
return true;
},
});
isEditableComment
By implementing this callback you have a fine grained control over which comments are read-only.
This callback will receive the Comment a user wants to modify and by returning true or
false you can define if the comment should be read-only (false) or modifiable (true).
To learn more check this guide article.
Example
Only allow the modification of comment from the same author.
NutrientViewer.load({
isEditableComment: function(comment) {
return comment.creatorName === myCurrentUser.name;
},
});
keyboardShortcutScope
Controls which SDK keyboard shortcuts the SDK intercepts globally, and which it restricts to "the user is interacting with the viewer."
{ scope: 'viewer' }(default) — No shortcuts are captured globally. Every shortcut fires only when the user has interacted with the viewer. The host page's own input fields keep native browser shortcuts (Cmd+Fopens browser Find,Cmd+Popens browser Print, etc.). Recommended for most applications.{ scope: 'global', interceptedActions: KeyboardShortcutActions[] }— The listed actions fire from anywhere on the page, including when the user is focused on a host-page element. Actions NOT in the list fall back to viewer-scope behavior. To restore the pre-2026 default of "every shortcut globally captured," pass every value of NutrientViewer.KeyboardShortcutActions.
Markup-toolbar shortcuts (highlight, strikeout, underline, etc.) are always viewer-scoped — they cannot be intercepted globally. In iframe mode, pagination keystrokes only fire from within the iframe.
Example
// Default: viewer scope (no shortcuts captured globally).
await NutrientViewer.load({
// ...
keyboardShortcutScope: { scope: 'viewer' },
})
// Pre-2026 behavior: every action captured globally.
await NutrientViewer.load({
// ...
keyboardShortcutScope: {
scope: 'global',
interceptedActions: [
NutrientViewer.KeyboardShortcutActions.SEARCH,
NutrientViewer.KeyboardShortcutActions.PRINT,
NutrientViewer.KeyboardShortcutActions.ZOOM,
NutrientViewer.KeyboardShortcutActions.UNDO,
NutrientViewer.KeyboardShortcutActions.REDO,
NutrientViewer.KeyboardShortcutActions.PAGINATION,
],
},
})
// Global capture for everything EXCEPT search — preserves browser Find.
await NutrientViewer.load({
// ...
keyboardShortcutScope: {
scope: 'global',
interceptedActions: [
NutrientViewer.KeyboardShortcutActions.PRINT,
NutrientViewer.KeyboardShortcutActions.ZOOM,
NutrientViewer.KeyboardShortcutActions.UNDO,
NutrientViewer.KeyboardShortcutActions.REDO,
NutrientViewer.KeyboardShortcutActions.PAGINATION,
],
},
})
Default Value
{ scope: 'viewer' }licenseKey
Standalone only
Nutrient Web SDK license key from https://my.nutrient.io/.
This isn't used for DWS Viewer API app-provided document loading; see session.
If neither licenseKey nor a DWS Viewer API session is provided, the instance will run
in trial mode for a limited time and then request the user to visit
https://www.nutrient.io/try/ to request a trial license.
Example
Activate with a license key
NutrientViewer.load({ licenseKey: "YOUR_LICENSE_KEY_GOES_HERE", document: 'https://example.com/document.pdf' });
locale
The initial locale (language) for the application.
All the available locales are defined in NutrientViewer.I18n.locales.
When a locale is not provided Nutrient Web SDK tries to autodetect the locale using window.navigator.language.
If the detected locale is not supported then the en locale is used instead.
Example
NutrientViewer.load({
locale: 'de',
// ...
});
logLevel
Verbosity of SDK initialization logging. Currently 'none' (default)
and 'debug'; more levels may be added in future releases.
Setting 'debug' emits tagged console.log lines at each init stage,
useful for diagnosing where a load stalls or fails. Can also be
enabled globally by setting globalThis.NUTRIENT_LOG_LEVEL = 'debug'
before the SDK module evaluates.
Example
NutrientViewer.load({
document: '/example.pdf',
container: '.viewer',
logLevel: NutrientViewer.LogLevel.DEBUG,
});
Default Value
NutrientViewer.LogLevel.NONEmaxDefaultZoomLevel
This property allows you to configure the maximum zoom level. The largest zoom level at a given time will be calculated based on the page proportions and this option. This is not necessarily a hard limit. For example, in order to satisfy the 'fit to width' and 'fit to page' zoom modes, the actual maximum zoom may be higher.
When omitted, the default is 10.
Example
NutrientViewer.load({ maxDefaultZoomLevel: 20 })
Default Value
10maxPasswordRetries
Defines how often the password modal is presented after a wrong password has been entered. By default, there won't be a limit for a regular Nutrient Web SDK installation.
When running in the headless mode, this option is ignored as we don't have an interface where
we could request a password (This is the same as setting maxPasswordRetries to 0).
Example
NutrientViewer.load({
maxPasswordRetries: 3,
// ...
});
measurementPrecision
| "whole"
| "oneDp"
| "twoDp"
| "threeDp"
| "fourDp"
| "1/2"
| "1/4"
| "1/8"
| "1/16"
Set the precision value of all the newly created measurement annotations.
Example
NutrientViewer.load({ measurementPrecision: NutrientViewer.MeasurementPrecision.THREE });
Default Value
NutrientViewer.MeasurementPrecision.TWOmeasurementScale
Set the default value of scale for all newly created measurement annotations.
Example
NutrientViewer.load(new NutrientViewer.MeasurementScale({
unitFrom: NutrientViewer.MeasurementScaleUnitFrom.CENTIMETERS,
unitTo: NutrientViewer.MeasurementScaleUnitTo.INCHES,
fromValue: 1,
toValue: 2,
}));
Default Value
1 inch = 1 inchmeasurementSnapping
Allows the user to toggle the snapping behavior while creation of measurement annotations. The snapping points are the points are a combination of endpoints, midpoints and intersections.
Example
NutrientViewer.load({ measurementSnapping: false });
Default Value
falseminDefaultZoomLevel
This property allows you to configure the minimum zoom level. The smallest zoom level at a given time will be calculated based on the page proportions and this option. This is not necessarily a hard limit. For example, in order to zoom out to show the entire page, the actual minimum zoom may be lower.
When omitted, the default is 0.5.
Example
NutrientViewer.load({ minDefaultZoomLevel: 0.1 })
Default Value
0.5nonce
A CSP nonce to apply to dynamically created <style> and <script> elements.
When your Content Security Policy uses nonce-based rules (e.g.
style-src 'nonce-...') instead of 'unsafe-inline', provide the
nonce value here so that all elements injected by the SDK are
permitted by the browser.
The nonce must match the value in your CSP header or <meta> tag for
the current page load.
Example
NutrientViewer.load({
nonce: "abc123",
// ...
});
officeConversionSettings
Standalone only
Configures how Office documents (e.g. DOCX, XLSX) are converted to PDF when loaded.
This is the load-time equivalent of the settings accepted by NutrientViewer.convertToPDF —
for example, controlling how tracked changes (revisions) in a DOCX are rendered via documentMarkupMode.
Example
NutrientViewer.load({
document: 'https://example.com/document.docx',
officeConversionSettings: {
documentMarkupMode: 'simpleMarkup',
},
// ...
});
Default Value
{ splitExcelSheetsIntoPages: false, spreadsheetRenderOnlyPrintArea: true, documentMarkupMode: 'noMarkup' }onAnnotationResizeStart
Allows to modify the default behavior when annotations are resized using the selection corner handles by returning an object. This provides more control over whether annotations should keep their aspect ratio when resized, for example.
Example
Unlock aspect ratio for the top left resize anchor
NutrientViewer.load({
onAnnotationResizeStart: event => {
return {
maintainAspectRatio: event.resizeAnchor === 'TOP_LEFT',
}
}
});
onAuthFailed
optional, Server only
Callback invoked when JWT tokens expire and soft refresh fails.
Implement this to fetch a new JWT and call setSession(newJwt) within 30 seconds.
If not called in time, the SDK throws and does not recover.
Example
NutrientViewer.load({
documentId: 'doc',
authPayload: { jwt: initialJwt },
onAuthFailed: async () => {
const newJwt = await fetchNewJwtFromBackend();
instance.setSession(newJwt);
},
});
onCommentCreationStart
You can programmatically modify the properties of the comment just before it is created.
Example
NutrientViewer.load({ onCommentCreationStart: comment => comment.set('text', { format: 'xhtml', value: '<p>Default text</p>' }) });
onInitialPageRender
This callback is called once for each page, the first time that page renders. It is registered before rendering starts, so it also observes the first page render, which makes it the supported way to measure the time to the first rendered page.
See OnInitialPageRenderCallback for when exactly it is called and what it guarantees.
Example
The first call reports whichever page renders first, which is not page 0 when the viewer
starts on another page.
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`);
},
// ...
});
onOpenURI
By default, all the URLs on which the user clicks explicitly open as expected but the URLs which open due to a result of JavaScript action are not opened due to security reasons.
You can override this behaviour using this callback. If this callback returns true, the URL will open.
Example
NutrientViewer.load({
onOpenURI: (url, isUserInitiated) => {
if (url.startsWith('https://abc.com') && isUserInitiated) {
return true
}
return false;
}
// ...
});
Default Value
undefinedonPasswordRequired
Called when the SDK needs a password to open an encrypted document. The callback
receives { filter, metadata } describing the encryption used:
- For standard password-protected files,
filteris'Standard'andmetadataisnull. - For files using a custom encryption filter that resolves to a standard PDF password
(e.g. Dedicon),
filteris the filter name as encoded in the PDF (e.g.'Dedicon') andmetadatacarries the filter-specific payload (for Dedicon, the embedded XML blob you can use to look up the actual password).
Resolve the returned promise to a password string to use it for the next attempt;
resolve to null/undefined to fall back to the built-in UI password prompt; reject
to abort opening the document. The callback is fired before the UI prompt on every
password failure (including retries), so it can centralise password resolution. As a
safety net, if the callback returns the same password that just failed, the SDK gives
up and rejects with the underlying password error instead of retrying indefinitely.
Example
NutrientViewer.load({
onPasswordRequired: async ({ filter, metadata }) => {
if (filter === 'Dedicon') {
return await resolveDediconPassword(metadata)
}
return null // fall back to the default password prompt UI
},
// ...
});
onWidgetAnnotationCreationStart
optional
You can programmatically modify the properties of the widget annotation and the associated form field just before it is created via the Form Creator UI.
Example
Set the opacity of all widget annotations.
NutrientViewer.load({
onWidgetAnnotationCreationStart: (annotation, formField) => {
return { annotation: annotation.set('opacity', 0.7) };
}
// ...
});
Default Value
undefinedoverprintPreview
Controls whether the renderer simulates overprinting used by the document.
Overprinting is a print-production technique where overlapping inks are printed on top of each other instead of knocking each other out. This option matters for prepress and soft-proofing workflows where the on-screen preview should match the printed output; typical screen-oriented documents are unaffected.
In server-backed mode, this option requires Document Engine 1.18.0 or later and is ignored by older servers.
Example
NutrientViewer.load({
overprintPreview: NutrientViewer.OverprintPreview.OFF,
// ...
});
Default Value
NutrientViewer.OverprintPreview.AUTOoverrideMemoryLimit
Overrides the allocable maximum memory when using Nutrient Web SDK Standalone. Only set this if you know that your users have web browsers with enough memory available.
This can improve rendering of documents with large images.
Example
NutrientViewer.load({
overrideMemoryLimit: 4096, // 4 GB
// ...
});
pageCacheSizeInBytes
Limits the estimated memory, in bytes, retained by Core's page cache when using Nutrient Web SDK Standalone. The currently active page may exceed this limit when it alone requires more memory.
Example
NutrientViewer.load({
pageCacheSizeInBytes: 256 * 1024 * 1024, // 256 MiB
// ...
});
Default Value
268435456pageRendering
Configures the page rendering engine.
Use "legacy" to keep the existing rendering pipeline.
Use "next" to opt in to the next-generation page rendering pipeline.
If left undefined, NutrientViewer currently defaults to "legacy".
Example
NutrientViewer.load({ pageRendering: "next" })
Default Value
undefinedpassword
If set, it will try to unlock the PDF with the provided password when loading it. PDFs which do not require a password won't open if this property is set.
Example
NutrientViewer.load({
password: 'secr3t',
// ...
});
populateInkSignatures
NutrientViewer.Immutable.List<
| NutrientViewer.Annotations.InkAnnotation
| NutrientViewer.Annotations.ImageAnnotation,
>,
>
Loads Ink Signatures when the UI displays them for the first time.
Ink Signatures are special Ink Annotations whose pageIndex and boundingBox are defined at creation time.
They can be converted to serializable objects with NutrientViewer.Annotations.toSerializableObject and stored as JSON using their InstantJSON format.
Serialized JSON annotations can be deserialized with JSON.parse and then converted to annotations with NutrientViewer.Annotations.fromSerializableObject.
Example
Populate Ink Signatures on demand.
NutrientViewer.load({
populateInkSignatures: () => {
return fetch('/signatures')
.then(r => r.json())
.then(a => (
NutrientViewer.Immutable.List(
a.map(NutrientViewer.Annotations.fromSerializableObject))
)
);
},
// ...
});
Default Value
() => Promise.resolve(NutrientViewer.Immutable.List())populateStoredSignatures
NutrientViewer.Immutable.List<
| NutrientViewer.Annotations.InkAnnotation
| NutrientViewer.Annotations.ImageAnnotation,
>,
>
Loads signatures when the UI displays them for the first time.
Signatures can be added as special Ink Annotations or Image Annotations whose pageIndex and boundingBox are defined at creation time.
They can be converted to serializable objects with NutrientViewer.Annotations.toSerializableObject and stored as JSON using their InstantJSON format.
Serialized JSON annotations can be deserialized with JSON.parse and then converted to annotations with NutrientViewer.Annotations.fromSerializableObject.
Example
Populate Signatures on demand.
NutrientViewer.load({
populateStoredSignatures: () => {
return fetch('/signatures')
.then(r => r.json())
.then(a => (
NutrientViewer.Immutable.List(
a.map(NutrientViewer.Annotations.fromSerializableObject))
)
);
},
// ...
});
Default Value
() => Promise.resolve(NutrientViewer.Immutable.List())preventTextCopy
When copying of text is disabled, it's still possible to select text but copying either using the shortcut or a context menu will have no effect.
This is implemented internally by listening to the copy event and prevent the default
implementation.
Please note that preventing text copying only provides limited security since the text will still be transmitted to the client.
Example
NutrientViewer.load({
preventTextCopy: true,
// ...
});
printMode
This property allows you to set the NutrientViewer.PrintMode to use.
Example
NutrientViewer.load({ printMode: NutrientViewer.PrintMode.DOM })
Default Value
NutrientViewer.PrintMode.DOMprintOptions
The printing mode and quality.
Determines whether printing a document renders each page as a bitmap image or prints a PDF directly.
| Property | Description |
|---|---|
| mode | NutrientViewer.PrintMode mode to use for printing. |
| quality | NutrientViewer.PrintQuality option to control bitmap quality used by |
Default Value
{ mode: NutrientViewer.PrintMode.DOM, quality: NutrientViewer.PrintQuality.LOW }processorEngine
optional, Standalone only
Document processing can be a time-consuming task, especially when working with large documents. In order to improve the user experience it is possible to choose between two different processor engines with different optimizations applied: either one with a smaller bundle size (the default), but slower overall performance, or one with a larger bundle size, but faster processing time.
Either case it's recommended to enable asset compression on your Server to improve loading time.
Example
NutrientViewer.load({ processorEngine: NutrientViewer.ProcessorEngine.fasterProcessing });
Default Value
NutrientViewer.ProcessorEngine.fasterProcessingproductId
optional, Standalone only
Allows specifying the environment in which the SDK is running.
Example
NutrientViewer.load({ productId: NutrientViewer.ProductId.SharePoint });
renderPageCallback
This callback is called whenever a page is rendered or printed (only for NutrientViewer.PrintMode.DOM). You can use it to render watermarks on the page.
Example
NutrientViewer.load({
renderPageCallback: function(ctx, pageIndex, pageSize) {
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(pageSize.width, pageSize.height);
ctx.stroke();
ctx.font = "30px Comic Sans MS";
ctx.fillStyle = "red";
ctx.textAlign = "center";
ctx.fillText(
`This is page ${pageIndex + 1}`,
pageSize.width / 2,
pageSize.height / 2
);
}
// ...
});
restrictAnnotationToPageBounds
This property allows you to restrict the movement of annotations to the page boundary. This is set to true by default.
If you want to disable this, you can set it to false.
Default Value
trueserverUrl
This allows you to overwrite the auto-detected Nutrient Document Engine URL. This setting is necessary when your Nutrient Document Engine is located under a different URL.
Example
NutrientViewer.load({ serverUrl: 'https://public-server.pspdfkit.com/' })
Default Value
Auto-detected based on the currently executed <script> tag.
session
Server and DWS Viewer API only
The session token or publishable key used to authenticate a DWS Viewer API or Document
Engine session.
When provided by itself, session opens the DWS-hosted document authorized by the token.
When provided together with document, session authorizes DWS Viewer API loading for
an app-provided document, such as a URL or ArrayBuffer. For that flow, use a publishable
DWS Viewer API key or create a documentless DWS Viewer API session by omitting document_id
and allowed_documents, and omit licenseKey.
Existing DWS Viewer API frontend sessions can also authorize app-provided document loading for compatibility, but browser-only integrations should use a publishable key.
Example
Load a DWS-hosted document
NutrientViewer.load({ session: 'xxx.xxx.xxx' });
Load an app-provided document with DWS Viewer API
NutrientViewer.load({
session: 'pdf_pub_live_...',
document: 'https://example.com/document.pdf',
});
signal
An optional AbortSignal that can be used to cancel the operation.
When the signal is aborted, the returned promise rejects with a
DOMException with name set to 'AbortError'. Any resources
allocated during the operation (backend, UI) are cleaned up.
For HTTP-based operations (document fetch, authentication), the underlying network request is cancelled. For WASM/worker operations, the promise rejects immediately but the underlying operation may run to completion in the background.
Example
const controller = new AbortController();
const loadPromise = NutrientViewer.load({
document: '/example.pdf',
container: '.viewer',
signal: controller.signal,
});
// Cancel loading after 5 seconds
setTimeout(() => controller.abort(), 5000);
try {
const instance = await loadPromise;
} catch (error) {
if (error.name === 'AbortError') {
console.log('Loading was cancelled');
}
}
stampAnnotationTemplates
This property allows you to set an initial list of stamp and image annotation templates for the NutrientViewer instance. This can be used to customize the list of available stamp and image annotation templates that will be available in the stamps picker UI before the application mounts.
When omitted, it will default to NutrientViewer.defaultStampAnnotationTemplates.
Example
const stampAnnotationTemplates = NutrientViewer.defaultStampAnnotationTemplates
stampAnnotationTemplates.push(new NutrientViewer.Annotations.StampAnnotation({
stampType: "Custom",
title: "My custom text",
boundingBox: new NutrientViewer.Geometry.Rect({
left: 0,
top: 0,
width: 300,
height: 100
})
}));
NutrientViewer.load({
stampAnnotationTemplates,
// Other configuration options
});
Default Value
standaloneInstancesPoolSize
Standalone only
Nutrient Web SDK uses an object pool to keep disposed instances in memory for fast reuse. Since this process can be memory inefficient, by default we only keep one instance in memory.
With this configuration option you can tune in the number of instances to keep in memory, or disable object pooling by setting this parameter to 0.
More about this feature: https://www.nutrient.io/blog/optimize-webassembly-startup-performance/
Example
NutrientViewer.load({
standaloneInstancesPoolSize: 2,
// ...
});
Default Value
1styleSheets
This will load your custom CSS as a <link rel="stylesheet"> inside the NutrientViewer component. This
is necessary to isolate styling of the viewer from the outside application and avoid external
stylesheets overwriting important viewer attributes.
An array is allowed to load multiple stylesheets. The order in the array will also be the order in which the stylesheets get loaded.
The array will be copied by us on start up time, which means that you can not mutate it after the viewer has started.
More information on how to style Nutrient Web SDK can be found in our guides.
Example
NutrientViewer.load({
styleSheets: [
'https://example.com/my-stylesheet.css',
'https://example.com/other-stylesheet.css'
]
})
Default Value
[]tempStorage
Standalone only
Controls where the SDK temporarily keeps document data while loading a document from a URL in standalone mode.
By default, the SDK manages this automatically. For larger eligible documents loaded from a URL, it prefers the browser's Origin Private File System (OPFS) to reduce peak memory usage. Documents that do not benefit from OPFS, or documents loaded through a different processing path, continue to use the in-memory path.
If OPFS is unavailable or initialization fails, the SDK falls back to the in-memory path. In that case, the document may be requested again.
For whole-document URL downloads, the OPFS path requires a valid Content-Length response
header so the SDK can pre-allocate storage. If that header is missing or invalid, the SDK
falls back to the in-memory path.
"auto"(default): Let the SDK manage temporary storage automatically. For larger eligible URL-loaded documents, the SDK prefers OPFS."memory": Always keep temporary document data in memory."opfs"or{ mode: 'opfs' }: Prefer OPFS for eligible URL-loaded documents regardless of file size.{ mode: 'opfs', minFileSize }: Prefer OPFS only when the file size is known and is at leastminFileSizebytes.
Example
NutrientViewer.load({
tempStorage: 'auto',
document: 'https://example.com/large-document.pdf',
// ...
});
Default Value
"auto"
theme
"AUTO" | "LIGHT" | "DARK" | "HIGH_CONTRAST_LIGHT" | "HIGH_CONTRAST_DARK" | { … }
This property allows you to set theme to use for the UI. See NutrientViewer.Theme
Note: You can customize the appearance of the UI using our public CSS classes. Please refer to this guide article for information on how to customize the appearance.
Example
NutrientViewer.load({ theme: NutrientViewer.Theme.DARK })
Default Value
NutrientViewer.Theme.LIGHTtileSize
This property allows you to change the size of the tiles used to render the document, in pixels. The bigger the tile, the fewer requests is made, but each tile will take longer to render.
This is useful for situations where you want to reduce the number of requests made to the server.
By default, the tile size is set to 512px in Nutrient Document Engine (server-backed) deployment, and 1536px in Standalone deployment.
Example
NutrientViewer.load({
tileSize: 1024
})
Default Value
512 in Nutrient Document Engine (server-backed), 1536 in StandalonetoolbarItems
This property allows you to set an initial list of toolbar items for the NutrientViewer instance. This can be used to customize the main toolbar before the application mounts.
When omitted, it will default to NutrientViewer.defaultToolbarItems.
Example
const toolbarItems = NutrientViewer.defaultToolbarItems;
toolbarItems.reverse();
NutrientViewer.load({
toolbarItems,
// Other configuration options
});
Default Value
toolbarPlacement
This property allows you to configure where the toolbar is placed. If nothing is configured, it will default to the top.
Example
NutrientViewer.load({ toolbarPlacement: NutrientViewer.ToolbarPlacement.TOP })
Default Value
NutrientViewer.ToolbarPlacement.TOPtrustedCAsCallback
required, Standalone only
By implementing this callback you have a fine grained control over which certificates are going to be used for digital signatures validation.
The callback must return an Array of ArrayBuffer (DER) or string (PEM)
containing X.509 certificates.
See this guide article to learn more.
Example
Fetch and use custom set of certificates (Standalone)
NutrientViewer.load({
trustedCAsCallback: function() {
return new Promise((resolve, reject) => {
fetch("/your-certificate.cer")
.then(res => res.arrayBuffer())
.then(cert => resolve([cert]))
.catch(reject)
});
},
// ...
})
ui
In-place UI customization API for the supported components using slots. Refer to this guide to get started.
Can be used to:
- fully replace the default component UI with a custom one
- insert a custom UI at a predefined slot in an existing component
- replace an existing slot in a component with your own custom UI
See the list of supported slots here.
Example
NutrientViewer.load({
ui: {
commentThread: {
header: (getInstance, id) => {
const header = document.createElement('div');
header.innerText = 'Custom Comment Thread Header';
return {
render: (params) => header,
onMount: (id) => {
console.log(`Comment thread header mounted`);
},
onUnmount: (id) => {
console.log(`Comment thread header unmounted`);
}
};
}
}
}
});
unstable_inkEraserMode
Allows to modify the default ink eraser behavior, which removes ink annotation points by default, changes it to make it remove entire strokes instead.
Deprecated
Use inkEraserMode instead.
Example
NutrientViewer.load({ unstable_inkEraserMode: NutrientViewer.unstable_InkEraserMode.STROKE });
Default Value
NutrientViewer.unstable_InkEraserMode.POINTuseCDN
This property is a temporary flag to explicitly enable loading assets from the CDN when
baseUrl is not provided. This flag will be removed in future releases once loading
from CDN is the default behavior when baseUrl is not set.
Has no effect when baseUrl is provided.
Default Value
falseXFDF
Standalone only
XFDF can be used to instantiate a viewer with a diff that is applied to the raw PDF. This format can be used to store annotation and form fields changes on your server and conveniently instantiate the viewer with the same content at a later time.
Instead of storing the updated PDF, this serialization only contains a diff that is applied on top of the existing PDF and thus allows you to cache the PDF and avoid transferring a potentially large PDF all the time.
You can export this format from a standalone instance by using Instance#exportXFDF.
Example
NutrientViewer.load({
XFDF: xfdfString,
// ...
});
XFDFIgnorePageRotation
Standalone only
Whether the imported XFDF should ignore the page rotation.
The default import behavior will take the page rotation into account.
This is useful when you have PDF pages that look the same, but have different underlying page rotations. Use in connection with Instance#exportXFDF ignorePageRotation parameter.
Example
NutrientViewer.load({
XFDF: xfdfString,
XFDFIgnorePageRotation: true,
// ...
});
Default Value
falseXFDFKeepCurrentAnnotations
Standalone only
Whether the annotations embedded in the PDF document should be kept instead of replaced importing XFDF.
The default import behavior will replace all annotations.
Example
NutrientViewer.load({
XFDF: xfdfString,
XFDFKeepCurrentAnnotations: true,
// ...
});
Default Value
falseXFDFRichTextEnabled
Standalone only
Whether the imported XFDF should have rich text annotations or not.
The default import behavior will convert rich text annotations to plain text annotations.
If set to true, rich text annotations will be supported and plain text annotations
will be converted to rich text annotations.
Example
NutrientViewer.load({
XFDF: xfdfString,
XFDFRichTextEnabled: true,
// ...
});
Default Value
false
Server only
This configuration describes a connection with AI Assistant service which provides AI capabilities directly in the viewer.