---
title: "Preserve PDF stamp template attachments | Nutrient"
canonical_url: "https://www.nutrient.io/guides/web/knowledge-base/image-attachments-lost-stamp-annotation-templates/"
md_url: "https://www.nutrient.io/guides/web/knowledge-base/image-attachments-lost-stamp-annotation-templates.md"
last_updated: "2026-05-19T09:44:53.563Z"
description: "When document operations are applied, either by calling NutrientViewer.Instance#applyOperations or using the Document Editor UI."
---

When document operations are applied, either by calling [`NutrientViewer.Instance#applyOperations`](https://www.nutrient.io/api/web/NutrientViewer.Instance.html#applyOperations) or using the [Document Editor UI](https://www.nutrient.io/guides/web/features/document-editor-ui.md), the current instance is reloaded to reflect the new version of the document. In that process, image attachments that aren’t currently used anywhere on the document are destroyed. Thus, if you had created some image annotations and added those as [stamp annotation templates](https://www.nutrient.io/guides/web/features/stamp-annotation-templates.md), their image attachments will no longer appear.

To avoid this, you can keep a cached copy of the image attachments in memory and recreate the image attachments once the document has changed. The code below is an example where we store the image attachments used on image annotations added for stamp annotation templates whenever the current interaction mode changes to [`NutrientViewer.InteractionMode#DOCUMENT_EDITOR`](https://www.nutrient.io/api/web/NutrientViewer.html#.InteractionMode) and restore that copy on [`document.change` events](https://www.nutrient.io/api/web/NutrientViewer.Instance.html#~DocumentChangeEvent):

```js

let instance = null;

// Object that will contain our attachments.
let attachmentsCache = null;

NutrientViewer.load({
  // Your configuration.
}).then(async (_instance) => {
  instance = _instance;
  const filePaths = ["a.png", "b.png"]; // Path to your images.
  const imageBlobs = await Promise.all(
    filePaths.map((name) =>
      fetch(`/assets/${name}`).then((response) => response.blob())
    )
  );
  const attachments = await Promise.all(
    imageBlobs.map((file) => instance.createAttachment(file))
  );
  const annotations = attachments.map(
    (imageAttachmentId) =>
      new NutrientViewer.Annotations.ImageAnnotation({
        imageAttachmentId,
        contentType: "image/png",
        boundingBox: new NutrientViewer.Geometry.Rect({
          width: 300,
          height: 200,
          top: 0,
          left: 0
        })
      })
  );

  // We add the image annotations created as stamp annotation templates.
  instance.setStampAnnotationTemplates((stampAnnotationTemplates) => [...annotations,...stampAnnotationTemplates
  ]);

  instance.addEventListener("viewState.change", (state) => {
    if (
      state.interactionMode === NutrientViewer.InteractionMode.DOCUMENT_EDITOR
    ) {
      // As soon as the document editor is opened, we cache the
      // current attachments used on stamp annotation templates.
      const attachmentIds = instance.stampAnnotationTemplates.filter((annotation) => annotation.imageAttachmentId).map((annotation) => annotation.imageAttachmentId);
      // We need to obtain the underlying blob
      // from the image attachment ID.
      attachmentsCache = Promise.all(
        attachmentIds.map((id) => instance.getAttachment(id))
      );
    }
  });
  instance.addEventListener("document.change", async () => {
    // "document.change" events are invoked after operations are
    // applied to the current instance.
    if (!attachmentsCache) {
      return;
    }
    const attachments = await attachmentsCache;
    await Promise.all(
      attachments.map((attachment) =>
        instance.createAttachment(attachment)
      )
    );
    // All attachments were recreated at this point.
  });
});

```

If document operations are applied programmatically using `NutrientViewer.Instance#applyOperations`, you can cache the current image attachments just before calling the method and recreate the attachments once the `Promise` returned by the former method resolves:

```js

let instance = null;

// Object that will contain our attachments.
let attachmentsCache = null;

NutrientViewer.load({
  // Your configuration.
}).then(async (_instance) => {
  instance = _instance;
  const filePaths = ["a.png", "b.png"]; // Path to your images.
  const imageBlobs = await Promise.all(
    filePaths.map((name) =>
      fetch(`/assets/${name}`).then((response) => response.blob())
    )
  );
  const attachments = await Promise.all(
    imageBlobs.map((file) => instance.createAttachment(file))
  );
  const annotations = attachments.map(
    (imageAttachmentId) =>
      new NutrientViewer.Annotations.ImageAnnotation({
        imageAttachmentId,
        contentType: "image/png",
        boundingBox: new NutrientViewer.Geometry.Rect({
          width: 300,
          height: 200,
          top: 0,
          left: 0
        })
      })
  );

  // We add the image annotations created as stamp annotation templates.
  instance.setStampAnnotationTemplates((stampAnnotationTemplates) => [...annotations,...stampAnnotationTemplates
  ]);
  const attachmentIds = instance.stampAnnotationTemplates.filter((annotation) => annotation.imageAttachmentId).map((annotation) => annotation.imageAttachmentId);
  // We need to obtain the underlying blob
  // from the image attachment ID.
  attachmentsCache = await Promise.all(
    attachmentIds.map((id) => instance.getAttachment(id))
  );

  const additionalPDF = await fetch(
    "assets/example.pdf"
  ).then((response) => response.blob());

  // Manually apply an "importDocument" operation.
  await instance.applyOperations([
    {
      type: "importDocument",
      afterPageIndex: instance.totalPageCount - 1,
      document: additionalPDF
    }
  ]);

  await Promise.all(
    attachmentsCache.map((attachment) =>
      instance.createAttachment(attachment)
    )
  );

  // All attachments were recreated at this point.
});

```

This has been tested with Nutrient Web SDK 2019.5.4.
---

## Related pages

- [How to add a custom toolbar item to display current zoom percentage](/guides/web/knowledge-base/add-custom-zoom-perentage.md)
- [Add Signature Initials](/guides/web/knowledge-base/add-signature-initials.md)
- [Add Listener Toolbar Item](/guides/web/knowledge-base/add-listener-toolbar-item.md)
- [Add Custom Keyboard Shortcuts](/guides/web/knowledge-base/add-custom-keyboard-shortcuts.md)
- [Add Listener Text Note Annotation](/guides/web/knowledge-base/add-listener-text-note-annotation.md)
- [Listen to an annotation’s hover event](/guides/web/knowledge-base/annotations-hover-event.md)
- [Keep widget annotation dimensions consistent across devices](/guides/web/knowledge-base/consistent-widget-annotation-dimensions.md)
- [Change Default Line Width Ink Annotations](/guides/web/knowledge-base/change-default-line-width-ink-annotations.md)
- [Default To Cloudy Border](/guides/web/knowledge-base/default-to-cloudy-border.md)
- [Check Password Protected Files](/guides/web/knowledge-base/check-password-protected-files.md)
- [Check Document Contains Annotations](/guides/web/knowledge-base/check-document-contains-annotations.md)
- [Customize Page Indicator](/guides/web/knowledge-base/customize-page-indicator.md)
- [Deselect Text](/guides/web/knowledge-base/deselect-text.md)
- [Blurry Print Resolution](/guides/web/knowledge-base/blurry-print-resolution.md)
- [Control Appearance Of Delete Button On Ink Annotations](/guides/web/knowledge-base/control-appearance-of-delete-button-on-ink-annotations.md)
- [Delete All Annotations](/guides/web/knowledge-base/delete-all-annotations.md)
- [Create Highlight Annotations From Text Extraction Technology](/guides/web/knowledge-base/create-highlight-annotations-from-text-extraction-technology.md)
- [Disable Context Menu](/guides/web/knowledge-base/disable-context-menu.md)
- [Export Ink Annotation Image](/guides/web/knowledge-base/export-ink-annotation-image.md)
- [Automatic Annotation Field Tab Ordering](/guides/web/knowledge-base/automatic-annotation-field-tab-ordering.md)
- [Extracting text and cursor position in annotations](/guides/web/knowledge-base/extract-annotation-text-and-retrieve-cursor-position.md)
- [How to disable text annotation movement in web apps](/guides/web/knowledge-base/disable-text-annotation-movement.md)
- [Determine Current Layout Mode](/guides/web/knowledge-base/determine-current-layout-mode.md)
- [Detect Pspdfkit Ui Loaded](/guides/web/knowledge-base/detect-pspdfkit-ui-loaded.md)
- [Disable Resize Of Annotations](/guides/web/knowledge-base/disable-resize-of-annotations.md)
- [Focus the delete button in a confirm dialog](/guides/web/knowledge-base/focus-delete-button-in-confirm-modal-component.md)
- [Download Exported Document](/guides/web/knowledge-base/download-exported-document.md)
- [Fix errors with unsupported form field actions](/guides/web/knowledge-base/handle-unsupported-form-field-actions.md)
- [Focus Viewer After Loading](/guides/web/knowledge-base/focus-viewer-after-loading.md)
- [Get Entered Document Password](/guides/web/knowledge-base/get-entered-document-password.md)
- [Find Ink Annotation For Signature Form Field](/guides/web/knowledge-base/find-ink-annotation-for-signature-form-field.md)
- [Handling Clicks On Custom Overlays](/guides/web/knowledge-base/handling-clicks-on-custom-overlays.md)
- [Focus Widget Annotation](/guides/web/knowledge-base/focus-widget-annotation.md)
- [Get Visible Annotations](/guides/web/knowledge-base/get-visible-annotations.md)
- [Highlight required form fields](/guides/web/knowledge-base/highlight-required-fields.md)
- [How Do I Disable Scrolling On Page Edges](/guides/web/knowledge-base/how-do-i-disable-scrolling-on-page-edges.md)
- [How Do I Limit The Number Of Annotations](/guides/web/knowledge-base/how-do-i-limit-the-number-of-annotations.md)
- [How To Create Bookmarks From Outline Elements](/guides/web/knowledge-base/how-to-create-bookmarks-from-outline-elements.md)
- [Resize multiline text fields to avoid overflow](/guides/web/knowledge-base/how-do-i-resize-form-fields.md)
- [How Do I Prevent Printing Annotations](/guides/web/knowledge-base/how-do-i-prevent-printing-annotations.md)
- [How Do I Rotate A Page](/guides/web/knowledge-base/how-do-i-rotate-a-page.md)
- [How Do I Toggle The Theme](/guides/web/knowledge-base/how-do-i-toggle-the-theme.md)
- [License Registered Different Bundle Id](/guides/web/knowledge-base/license-registered-different-bundle-id.md)
- [Link Text](/guides/web/knowledge-base/link-text.md)
- [Loading Multiple Files](/guides/web/knowledge-base/loading-multiple-files.md)
- [Iterate over form fields and widgets](/guides/web/knowledge-base/iterate-over-form-fields.md)
- [How Do I Zoom To A Specific Value](/guides/web/knowledge-base/how-do-i-zoom-to-a-specific-value.md)
- [Disabling automatic synchronization in Nutrient Web SDK](/guides/web/knowledge-base/manual-instant-sync.md)
- [Nutrient Size Optimization](/guides/web/knowledge-base/nutrient-size-optimization.md)
- [Load Pdf As Arraybuffer](/guides/web/knowledge-base/load-pdf-as-arraybuffer.md)
- [Load Pdf Stub From String](/guides/web/knowledge-base/load-pdf-stub-from-string.md)
- [Load Pdf From Stream](/guides/web/knowledge-base/load-pdf-from-stream.md)
- [Observe Document Editor Visibility](/guides/web/knowledge-base/observe-document-editor-visibility.md)
- [Persist Ink Signatures Across Instances](/guides/web/knowledge-base/persist-ink-signatures-across-instances.md)
- [Override Ink Signature Dialog](/guides/web/knowledge-base/override-ink-signature-dialog.md)
- [Persist Currently Edited Note Test](/guides/web/knowledge-base/persist-currently-edited-note-test.md)
- [Override User Agent](/guides/web/knowledge-base/override-user-agent.md)
- [Overview](/guides/web/knowledge-base/overview.md)
- [Process Currently Rendered Pages](/guides/web/knowledge-base/process-currently-rendered-pages.md)
- [Programmatically Navigate To Page](/guides/web/knowledge-base/programmatically-navigate-to-page.md)
- [Programmatic Comment Annotations](/guides/web/knowledge-base/programmatic-comment-annotations.md)
- [Render Page Black White](/guides/web/knowledge-base/render-page-black-white.md)
- [Place Annotation At Visible Center](/guides/web/knowledge-base/place-annotation-at-visible-center.md)
- [Prevent Editing Content Text Annotation](/guides/web/knowledge-base/prevent-editing-content-text-annotation.md)
- [Prevent Shortcut Printing](/guides/web/knowledge-base/prevent-shortcut-printing.md)
- [Read-only forms](/guides/web/knowledge-base/read-only-forms.md)
- [Render Document Full Height](/guides/web/knowledge-base/render-document-full-height.md)
- [Render Page Without Annotations](/guides/web/knowledge-base/render-page-without-annotations.md)
- [Render Night Mode](/guides/web/knowledge-base/render-night-mode.md)
- [Save Modified Pdf To Document Engine](/guides/web/knowledge-base/save-modified-pdf-to-document-engine.md)
- [Render Visible Area In Current Page](/guides/web/knowledge-base/render-visible-area-in-current-page.md)
- [Rotate Ink Annotation](/guides/web/knowledge-base/rotate-ink-annotation.md)
- [Render Watermark When Printing](/guides/web/knowledge-base/render-watermark-when-printing.md)
- [Show Focus Ring Read Only](/guides/web/knowledge-base/show-focus-ring-read-only.md)
- [Web Sdk Vs Dws Viewer](/guides/web/knowledge-base/web-sdk-vs-dws-viewer.md)
- [Restore Last Seen Page](/guides/web/knowledge-base/restore-last-seen-page.md)
- [Wait For Element Appear](/guides/web/knowledge-base/wait-for-element-appear.md)
- [Show Annotations Properties As Tooltip](/guides/web/knowledge-base/show-annotations-properties-as-tooltip.md)
- [Easily zoom to specific annotations in PDF](/guides/web/knowledge-base/zoom-to-specific-annotation.md)
- [Submit Ink Signatures With Form](/guides/web/knowledge-base/submit-ink-signatures-with-form.md)

