### Clone and Run Nutrient Web SDK Examples Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/README.md Use these commands to clone the repository and start the example catalog using Docker. Ensure Docker is installed. ```sh git clone https://github.com/PSPDFKit/pspdfkit-web-examples-catalog.git cd pspdfkit-web-examples-catalog docker-compose up ``` -------------------------------- ### Build and Start Catalog in Production Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/CLAUDE.md Build the catalog for production and then start the server from the catalog directory. ```bash pnpm build && pnpm start ``` -------------------------------- ### Start Catalog Development Server Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/CLAUDE.md Use this command to start the catalog in development mode with hot reload from the catalog directory. ```bash pnpm dev ``` -------------------------------- ### Start Catalog from Parent Directory Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/CLAUDE.md Initiate the catalog on port 3000 by running this command from the parent directory. ```bash pnpm start:catalog ``` -------------------------------- ### PSPDFKit Load Pattern Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/CLAUDE.md This JavaScript pattern shows the basic structure for loading PSPDFKit in an example. It includes importing the SDK and exporting a load function that accepts default configuration. ```javascript import PSPDFKit from "@nutrient-sdk/viewer" export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, // Custom configuration }).then(instance => { // Post-load operations return instance }) } ``` -------------------------------- ### Retrieve Instant Document Metadata Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Use this endpoint to get JWT, document ID, and URLs for opening documents in native PDF Viewer apps. Requires `Accept: application/vnd.instant-example+json` header. ```bash curl http://localhost:3000/api/instant/01cgv5hzxph8xkd135c5rnxkdc.hZbzNKoxxzFKdl27Hxv4TQ # Response # { # "encodedDocumentId": "01cgv5hzxph8xkd135c5rnxkdc.hZbzNKoxxzFKdl27Hxv4TQ", # "documentId": "01cgv5hzxph8xkd135c5rnxkdc", # "jwt": "", # "url": "http://localhost:3000/hello?inapp=true&i=01cgv5hzxph8xkd135c5rnxkdc.hZbzNKoxxzFKdl27Hxv4TQ", # "serverUrl": "http://document-engine:5000" # } ``` -------------------------------- ### PSPDFKit.preloadWorker(configuration) Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Starts loading the WebAssembly worker in the background before `PSPDFKit.load()` is called, which helps in reducing the perceived load time of the viewer. ```APIDOC ## PSPDFKit.preloadWorker(configuration) — Preload the WebAssembly worker ### Description Starts loading the WebAssembly worker in the background before `PSPDFKit.load()` is called, reducing perceived load time. ### Method `PSPDFKit.preloadWorker(configuration)` ### Parameters #### Configuration Object - **configuration** (object) - The configuration object, typically the same one passed to `PSPDFKit.load()`. ``` -------------------------------- ### Force Specific Backend via URL Parameter Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/README.md Append the `mode` query parameter to a URL to force either the "standalone" or "server" backend for the catalog examples. Example: `?mode=standalone`. ```url https://web-examples.our.services.nutrient-powered.io/hello?mode=standalone ``` -------------------------------- ### Reset Docker Environment Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/README.md To reset the Nutrient Web SDK example environment, tear down existing containers and volumes, then recreate them. This is useful for troubleshooting. ```sh docker-compose down --volumes docker-compose up ``` -------------------------------- ### Preload WebAssembly Worker with PSPDFKit.preloadWorker() Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Starts loading the WebAssembly worker in the background before PSPDFKit.load() is called, which can reduce the perceived load time of the viewer. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { // Start loading the worker immediately PSPDFKit.preloadWorker(defaultConfiguration); return PSPDFKit.load(defaultConfiguration).then((instance) => instance); } ``` -------------------------------- ### Obtain a JWT and document session Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt The Express server uploads the example PDF to Document Engine on first request, then returns the document ID, a shareable ID, and a signed JWT for the viewer. ```APIDOC ## Server-Side APIs ### `POST /server-document/:name` — Obtain a JWT and document session #### Description The Express server uploads the example PDF to Document Engine on first request, then returns the document ID, a shareable ID, and a signed JWT for the viewer. #### Request Example ```bash # Request a session for the "hello" example curl -X POST http://localhost:3000/server-document/hello \ -H "Content-Type: application/json" \ -d '{}' ``` #### Response Example ```json { "documentId": "01cgv5hzxph8xkd135c5rnxkdc", "id": "01cgv5hzxph8xkd135c5rnxkdc.hZbzNKoxxzFKdl27Hxv4TQ.tdAY", "jwt": "", "aiaJwt": "" } ``` ``` -------------------------------- ### Obtain JWT and Document Session via Server API Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Demonstrates how to request a document session from a server. Uploads an example PDF to Document Engine and returns document and session IDs, along with a JWT for viewer authentication. Uses cURL for the request. ```bash # Request a session for the "hello" example curl -X POST http://localhost:3000/server-document/hello \ -H "Content-Type: application/json" \ -d '{}' # Response # { # "documentId": "01cgv5hzxph8xkd135c5rnxkdc", # "id": "01cgv5hzxph8xkd135c5rnxkdc.hZbzNKoxxzFKdl27Hxv4TQ.tdAY", # "jwt": "", # "aiaJwt": "" # } ``` -------------------------------- ### Convert Office Documents to PDF and Export PDF to Office Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Converts Office documents (DOCX, PPTX, XLSX) to PDF, or exports a loaded PDF back to an Office format. This example shows exporting a PDF to DOCX and standalone DOCX to PDF conversion. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load(defaultConfiguration).then(async (instance) => { // Export the current PDF to DOCX const docxBuffer = await instance.exportOffice({ format: PSPDFKit.OfficeDocumentFormat.docx, }); const blob = new Blob([docxBuffer], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", }); const url = URL.createObjectURL(blob); const a = Object.assign(document.createElement("a"), { href: url, download: "exported.docx", }); a.click(); URL.revokeObjectURL(url); return instance; }); } // Standalone conversion: DOCX → PDF without loading the viewer PSPDFKit.convertToPDF( { ...defaultConfiguration, document: "/path/to/file.docx" }, PSPDFKit.Conformance.PDFA_2B // optional PDF/A conformance level ).then((pdfBuffer) => { const blob = new Blob([pdfBuffer], { type: "application/pdf" }); // trigger download or process buffer... }); ``` -------------------------------- ### Initialize PDF Viewer with PSPDFKit.load() Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt The primary entry point for initializing the PDF viewer. Accepts a configuration object and returns a Promise resolving to an instance. The default configuration includes container, document URL or auth payload, and license key. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, // container, document/authPayload, licenseKey enableHistory: true, // enable undo/redo history toolbarItems: [ ...PSPDFKit.defaultToolbarItems, { type: "content-editor" }, // add the content editor tool ], }).then((instance) => { console.log("PSPDFKit loaded:", instance); return instance; }); } ``` -------------------------------- ### PSPDFKit.load(configuration) Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt The primary entry point for initializing the PDF viewer. It accepts a configuration object and returns a Promise that resolves to an instance of the viewer. ```APIDOC ## PSPDFKit.load(configuration) — Initialize the PDF viewer ### Description The primary entry point for initializing the PDF viewer. Accepts a configuration object and returns a Promise resolving to an `instance`. The `defaultConfiguration` passed to every example's `load()` function already contains the container, document URL or auth payload, license key, and other defaults injected by the catalog server. ### Method `PSPDFKit.load(configuration)` ### Parameters #### Configuration Object - **container** (string | HTMLElement) - The DOM element or selector for the viewer container. - **document** (string | object) - The URL of the PDF document or an authentication payload. - **licenseKey** (string) - The license key for PSPDFKit. - **enableHistory** (boolean) - Optional. Enables undo/redo history. - **toolbarItems** (Array) - Optional. An array of toolbar item configurations. - **theme** (PSPDFKit.Theme) - Optional. Sets the viewer theme (e.g., `PSPDFKit.Theme.DARK`, `PSPDFKit.Theme.LIGHT`). ### Request Example ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, // container, document/authPayload, licenseKey enableHistory: true, // enable undo/redo history toolbarItems: [ ...PSPDFKit.defaultToolbarItems, { type: "content-editor" }, // add the content editor tool ], }).then((instance) => { console.log("PSPDFKit loaded:", instance); return instance; }); } ``` ### Response #### Success Response - **instance** (PSPDFKitInstance) - A Promise resolving to the PSPDFKit instance. ``` -------------------------------- ### Configure Viewer Theme (Dark Mode) Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Set the viewer theme at load time by passing `theme: PSPDFKit.Theme.DARK` or `theme: PSPDFKit.Theme.LIGHT` in the configuration object. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, theme: PSPDFKit.Theme.DARK, }).then((instance) => { console.log("Loaded in dark mode:", instance); return instance; }); } ``` -------------------------------- ### Redact Content in PDF Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Marks content for redaction by text, regex, or preset pattern, previews the result, then permanently applies it. This example marks all credit card numbers for redaction. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, toolbarItems: [ ...PSPDFKit.defaultToolbarItems, { type: "redact-rectangle" }, { type: "redact-text-highlighter" }, ], }).then(async (instance) => { // Mark all credit card numbers for redaction using a built-in preset const matches = await instance.createRedactionsBySearch( PSPDFKit.SearchPattern.CREDIT_CARD_NUMBER, { searchType: PSPDFKit.SearchType.PRESET, searchInAnnotations: true, } ); console.log(`Marked ${matches.size} areas for redaction`); // Preview mode (shows redacted areas highlighted) instance.setViewState((vs) => vs.set("previewRedactionMode", true)); // Permanently apply all redaction annotations (irreversible) // instance.applyRedactions(); return instance; }); } ``` -------------------------------- ### Run with Activation Key Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/README.md To run the environment with your Nutrient Document Engine activation key, update the docker-compose.yml file and use this command. This is for licensed users. ```sh ACTIVATION_KEY=YOUR_ACTIVATION_KEY_GOES_HERE docker-compose up ``` -------------------------------- ### Run with Activation Key on Windows Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/README.md For Windows users, set the environment variable for the activation key using the SET command before running docker-compose up. ```shell SET "ACTIVATION_KEY=YOUR_ACTIVATION_KEY_GOES_HERE" docker-compose up ``` -------------------------------- ### Creating Annotations Programmatically Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Construct annotation objects using `PSPDFKit.Annotations.*` constructors and submit them via `instance.create()`. Supports various annotation types like ink, text, highlight, and more. ```APIDOC ## Creating annotations programmatically — `instance.create()` Construct annotation objects using `PSPDFKit.Annotations.*` constructors and submit them via `instance.create()`. Supports ink, text, highlight, ellipse, note, image, redaction, and more. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, enableHistory: true }) .then(async (instance) => { const changes = await instance.create([ // Ink annotation with drawn lines new PSPDFKit.Annotations.InkAnnotation({ pageIndex: 0, boundingBox: new PSPDFKit.Geometry.Rect({ left: 50, top: 50, width: 150, height: 50 }), strokeColor: PSPDFKit.Color.BLUE, lines: PSPDFKit.Immutable.List([ PSPDFKit.Immutable.List([ new PSPDFKit.Geometry.DrawingPoint({ x: 50, y: 75 }), new PSPDFKit.Geometry.DrawingPoint({ x: 200, y: 75 }), ]), ]), }), // Bold text annotation with colored background new PSPDFKit.Annotations.TextAnnotation({ pageIndex: 0, boundingBox: new PSPDFKit.Geometry.Rect({ left: 50, top: 150, width: 150, height: 60 }), text: { format: "plain", value: "Hello Nutrient!" }, isBold: true, horizontalAlign: "center", verticalAlign: "center", backgroundColor: PSPDFKit.Color.BLUE, fontColor: PSPDFKit.Color.WHITE, }), // Sticky note annotation new PSPDFKit.Annotations.NoteAnnotation({ pageIndex: 0, text: { format: "plain", value: "Review this section." }, boundingBox: new PSPDFKit.Geometry.Rect({ left: 500, top: 20, width: 30, height: 30 }), }), ]); const saved = await instance.ensureChangesSaved(changes); console.log("Saved annotation IDs:", saved.map((a) => a.id).join(", ")); return instance; }); } ``` ``` -------------------------------- ### Encode and Decode Shareable Document IDs Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Use `encodeShareableId` to create a URL-safe string from a document ID, layer name, and optional example name. Use `decodeShareableId` to retrieve these components. ```javascript const { encodeShareableId, decodeShareableId, createLayerName, createExampleHash, } = require("./_server/lib/shareable-ids"); // Encode const layerName = createLayerName(); // 128-bit random, URL-safe base64 const shareableId = encodeShareableId("my-doc-id", layerName, "hello"); // e.g. "my-doc-id.hZbzNKoxxzFKdl27Hxv4TQ.tdAY" // Decode const [documentId, layer, exampleHash] = decodeShareableId(shareableId); console.log(documentId); // "my-doc-id" console.log(layer); // "hZbzNKoxxzFKdl27Hxv4TQ" console.log(exampleHash);// "tdAY" (truncated SHA256 of "hello") ``` -------------------------------- ### Add Custom Overlay Item to PDF Page Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Places arbitrary DOM elements on top of specific page positions using PSPDFKit.CustomOverlayItem. This example adds a div to the page when the user clicks on it. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load(defaultConfiguration).then((instance) => { instance.addEventListener("page.press", (event) => { const el = document.createElement("div"); el.style.cssText = "background:#fff;border:1px solid #333;padding:16px;font-family:sans-serif;"; el.textContent = `You clicked page ${event.pageIndex}`; instance.setCustomOverlayItem( new PSPDFKit.CustomOverlayItem({ id: "click-overlay", node: el, pageIndex: event.pageIndex, position: new PSPDFKit.Geometry.Point({ x: 200, y: 100 }), }) ); }); return instance; }); } ``` -------------------------------- ### Create Annotations Programmatically Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Use `instance.create()` with `PSPDFKit.Annotations.*` constructors to programmatically add various annotation types, such as ink, text, and notes. Ensure changes are saved using `instance.ensureChangesSaved()`. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, enableHistory: true }) .then(async (instance) => { const changes = await instance.create([ // Ink annotation with drawn lines new PSPDFKit.Annotations.InkAnnotation({ pageIndex: 0, boundingBox: new PSPDFKit.Geometry.Rect({ left: 50, top: 50, width: 150, height: 50 }), strokeColor: PSPDFKit.Color.BLUE, lines: PSPDFKit.Immutable.List([ PSPDFKit.Immutable.List([ new PSPDFKit.Geometry.DrawingPoint({ x: 50, y: 75 }), new PSPDFKit.Geometry.DrawingPoint({ x: 200, y: 75 }), ]), ]), }), // Bold text annotation with colored background new PSPDFKit.Annotations.TextAnnotation({ pageIndex: 0, boundingBox: new PSPDFKit.Geometry.Rect({ left: 50, top: 150, width: 150, height: 60 }), text: { format: "plain", value: "Hello Nutrient!" }, isBold: true, horizontalAlign: "center", verticalAlign: "center", backgroundColor: PSPDFKit.Color.BLUE, fontColor: PSPDFKit.Color.WHITE, }), // Sticky note annotation new PSPDFKit.Annotations.NoteAnnotation({ pageIndex: 0, text: { format: "plain", value: "Review this section." }, boundingBox: new PSPDFKit.Geometry.Rect({ left: 500, top: 20, width: 30, height: 30 }), }), ]); const saved = await instance.ensureChangesSaved(changes); console.log("Saved annotation IDs:", saved.map((a) => a.id).join(", ")); return instance; }); } ``` -------------------------------- ### Generate Viewer JWT (Node.js) Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Sign an RS256 JWT for viewer access with `read-document`, `write`, and `download` permissions. It defaults to a 3-day expiration. Also includes an example for generating a short-lived processing JWT. ```javascript const { createJwt, createJwtForProcessing } = require("./_server/lib/jwt"); // Standard viewer JWT (3-day expiry, full permissions) const jwt = createJwt( "my-document-id", "user-layer-abc123", { user_id: "user-42" } // optional extra payload claims ); // Short-lived processing JWT (1-hour expiry, for DWS operations) const processingJwt = createJwtForProcessing({ allowed_operations: ["pdf-convert"], server_url: "https://document-engine.example.com", }); ``` -------------------------------- ### Theme Configuration Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Allows setting the viewer theme to dark or light mode by passing a theme option in the configuration object during initialization. ```APIDOC ## Theme configuration — Dark mode ### Description Pass `theme: PSPDFKit.Theme.DARK` (or `LIGHT`) in the configuration object to set the viewer theme at load time. ### Method `PSPDFKit.load(configuration)` ### Parameters #### Configuration Object - **theme** (PSPDFKit.Theme) - Required/Optional - Sets the viewer theme. Use `PSPDFKit.Theme.DARK` for dark mode or `PSPDFKit.Theme.LIGHT` for light mode. ### Request Example ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, theme: PSPDFKit.Theme.DARK, }).then((instance) => { console.log("Loaded in dark mode:", instance); return instance; }); } ``` ``` -------------------------------- ### Reset Environment with Activation Key Source: https://github.com/pspdfkit/pspdfkit-web-examples-catalog/blob/master/README.md If using an activation key, reset the environment by tearing down volumes and recreating containers, then re-apply the activation key. ```sh docker-compose down --volumes ACTIVATION_KEY=YOUR_ACTIVATION_KEY_GOES_HERE docker-compose up ``` -------------------------------- ### Load Annotations and Comments with Instant JSON Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Load pre-existing annotations and threaded comments at viewer startup using the Instant JSON format. Additional comment threads can be created programmatically after load. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, instantJSON: { format: "https://pspdfkit.com/instant-json/v1", annotations: [ { type: "pspdfkit/comment-marker", id: "01HV60ME365HS69FVQ1CE6PK2G", pageIndex: 0, bbox: [162, 145, 32, 32], isCommentThreadRoot: true, v: 2, }, ], comments: [ { type: "pspdfkit/comment", id: "01HV60MEZC5Q4VC76NSKFDPYK9", rootId: "01HV60ME365HS69FVQ1CE6PK2G", pageIndex: 0, text: { format: "xhtml", value: "

Initial comment via instantJSON

" }, v: 2, }, ], }, }).then(async (instance) => { // Programmatically add another comment thread after load const marker = new PSPDFKit.Annotations.CommentMarkerAnnotation({ id: PSPDFKit.generateInstantId(), pageIndex: 0, boundingBox: new PSPDFKit.Geometry.Rect({ left: 250, top: 250, width: 32, height: 32 }), }); await instance.create([ marker, new PSPDFKit.Comment({ rootId: marker.id, pageIndex: 0, text: { format: "plain", value: "Programmatically added comment." }, }), ]); return instance; }); } ``` -------------------------------- ### Retrieve Instant Document Metadata Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Fetches JWT, document ID, server URL, and a deep-link URL for opening a document in native PDF Viewer apps. This endpoint is typically called with `Accept: application/vnd.instant-example+json` from mobile apps. ```APIDOC ## GET /api/instant/:id ### Description Retrieves Instant document metadata, including JWT, document ID, server URL, and a deep-link URL. ### Method GET ### Endpoint /api/instant/:id ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the Instant document. ### Response #### Success Response (200) - **encodedDocumentId** (string) - The encoded document ID. - **documentId** (string) - The document ID. - **jwt** (string) - The JWT for accessing the document. - **url** (string) - A deep-link URL for opening the document. - **serverUrl** (string) - The URL of the document server. ### Request Example ```bash curl http://localhost:3000/api/instant/01cgv5hzxph8xkd135c5rnxkdc.hZbzNKoxxzFKdl27Hxv4TQ ``` ### Response Example ```json { "encodedDocumentId": "01cgv5hzxph8xkd135c5rnxkdc.hZbzNKoxxzFKdl27Hxv4TQ", "documentId": "01cgv5hzxph8xkd135c5rnxkdc", "jwt": "", "url": "http://localhost:3000/hello?inapp=true&i=01cgv5hzxph8xkd135c5rnxkdc.hZbzNKoxxzFKdl27Hxv4TQ", "serverUrl": "http://document-engine:5000" } ``` ``` -------------------------------- ### Load Custom Fonts with `customFonts` Configuration Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Register additional fonts for use in the content editor and form creator. The `callback` function should fetch the font file and return it as a Blob. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, enableHistory: true, customFonts: [ new PSPDFKit.Font({ name: "SourceHanSerif.ttf", // Fetch the font file and return it as a Blob callback: (name) => fetch(`/custom-fonts/static/${name}`).then((res) => res.blob()), }), ], }).then((instance) => instance); } ``` -------------------------------- ### Listen for Annotation Lifecycle Events Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Use `instance.addEventListener` to subscribe to annotation lifecycle events like load, create, update, and delete. This is useful for reacting to changes in annotations. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, enableHistory: true }) .then(async (instance) => { instance.addEventListener("annotations.load", (loaded) => { console.log("Loaded annotations:", loaded.toJS()); }); instance.addEventListener("annotations.create", (created) => { console.log("Created:", created.toJS()); }); instance.addEventListener("annotations.update", (updated) => { console.log("Updated:", updated.toJS()); }); instance.addEventListener("annotations.delete", (deleted) => { console.log("Deleted:", deleted.toJS()); }); return instance; }); } ``` -------------------------------- ### Customize Toolbar Items with toolbarItems and PSPDFKit.defaultToolbarItems Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Customize the viewer's toolbar by filtering, reordering, or appending to `PSPDFKit.defaultToolbarItems`. Custom items can execute arbitrary callbacks via `onPress`. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { let instance = null; // Keep only specific built-in tools const toolbarItems = PSPDFKit.defaultToolbarItems.filter((item) => /sidebar-bookmarks|sidebar-thumbnails|zoom-in|zoom-out/.test(item.type) ); toolbarItems.push({ type: "spacer" }); // Add a fully custom button toolbarItems.push({ type: "custom", id: "my-custom-button", title: "SDK Version", onPress: () => { alert( `Nutrient Web SDK ${PSPDFKit.version} — page ${instance.viewState.currentPageIndex}` ); }, }); toolbarItems.push({ type: "search" }); return PSPDFKit.load({ ...defaultConfiguration, toolbarItems, }).then((newInstance) => { instance = newInstance; return instance; }); } ``` -------------------------------- ### Retrieve Signing Certificates Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Fetch available signing certificates from Document Engine or Document Web Services. The response structure may vary depending on the backend used. ```bash # From Document Engine curl http://localhost:3000/api/get-certificates # From Document Web Services curl "http://localhost:3000/api/get-certificates?backend=dws" # Response (structure varies by backend) # { "data": { "certificates": [...] } } ``` -------------------------------- ### Measurement tools Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Add the built-in distance, perimeter, area, and angle measurement tools to the toolbar. ```APIDOC ## Measurement tools — `measure` toolbar item ### Description Add the built-in distance, perimeter, area, and angle measurement tools to the toolbar. ### Usage ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { return PSPDFKit.load({ ...defaultConfiguration, toolbarItems: [...PSPDFKit.defaultToolbarItems, { type: "measure" }], }).then((instance) => { window.instance = instance; return instance; }); } ``` ``` -------------------------------- ### Create Multi-layer Collaboration Session Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Initiate a collaboration session by providing a list of layer names. The API returns per-layer JWT metadata for multiple users to work on separate annotation layers of the same document. ```bash curl -X POST http://localhost:3000/api/construction-plan \ -H "Content-Type: application/json" \ -d '{"layers": ["alice", "bob", "charlie"]}' # Response # { # "alice": { "documentId": "construction-plan", "jwt": "...", "url": "..." }, # "bob": { "documentId": "construction-plan", "jwt": "...", "url": "..." }, # "charlie":{ "documentId": "construction-plan", "jwt": "...", "url": "..." } # } ``` -------------------------------- ### Manage Ink Signatures with `populateInkSignatures` and `getInkSignatures` Source: https://context7.com/pspdfkit/pspdfkit-web-examples-catalog/llms.txt Pre-populate the signature selection dialog and persist user signatures to `localStorage` between sessions. The `populateInkSignatures` function is called at load time, and an event listener persists changes. ```javascript import PSPDFKit from "@nutrient-sdk/viewer"; export function load(defaultConfiguration) { let instance = null; return PSPDFKit.load({ ...defaultConfiguration, // Called at load time to supply previously saved ink signatures populateInkSignatures() { const json = localStorage.getItem("inkSignatures"); const raw = json ? JSON.parse(json) : []; return PSPDFKit.Immutable.List( raw.map(PSPDFKit.Annotations.fromSerializableObject) ); }, }).then((_instance) => { instance = _instance; // Persist changes whenever signatures are added/updated/removed instance.addEventListener("inkSignatures.change", async () => { const sigs = await instance.getInkSignatures(); localStorage.setItem( "inkSignatures", JSON.stringify( sigs.map(PSPDFKit.Annotations.toSerializableObject).toJS() ) ); }); return instance; }); } ```