---
title: "JavaScript PDF viewer with watermark | Nutrient SDK"
canonical_url: "https://www.nutrient.io/guides/web/features/watermarks/"
md_url: "https://www.nutrient.io/guides/web/features/watermarks.md"
last_updated: "2026-05-22T22:19:39.099Z"
description: "Learn how to use Nutrient’s RenderPageCallback API to draw dynamic watermarks on PDF pages. Perfect for customizing document presentations effortlessly."
---

# Render watermarks in our JavaScript PDF viewer

An app using Nutrient Web SDK can draw content on top of a PDF using the [`RenderPageCallback`](https://www.nutrient.io/api/web/NutrientViewer.html#.RenderPageCallback) API. This API allows you to configure a callback that’s executed with a reference to the page canvas. You can use it to draw additional information — watermarks, for example — on top of a PDF.

These rendered watermarks won’t be persisted to the document when saving.

## Using RenderPageCallback

Whenever a page is rendered or printed (only for [`NutrientViewer.PrintMode.DOM`](https://www.nutrient.io/api/web/NutrientViewer.html#.PrintMode)), you can use [`RenderPageCallback`](https://www.nutrient.io/api/web/NutrientViewer.html#.RenderPageCallback) to render watermarks on the page.

To do this, define a [`Configuration#renderPageCallback`](https://www.nutrient.io/api/web/NutrientViewer.Configuration.html#renderPageCallback) function in which you execute your canvas drawing commands:

```js

NutrientViewer.load({
  renderPageCallback(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
    );
  }
  //...
});

```

Within the callback, you have access to [`CanvasRenderingContext2D`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D) and additional properties like the current `pageIndex` and the `pageSize`.

Make sure that the rendering commands are as efficient as possible, as they might be invoked multiple times per page (once per tile).

When you’re using the [`RenderPageCallback`](https://www.nutrient.io/api/web/NutrientViewer.html#.RenderPageCallback) API to draw content on the page, the changes will only be visible on the client, and the exported PDF won’t include these drawings. They will, however, be part of the printed page when using [`NutrientViewer.PrintMode.DOM`](https://www.nutrient.io/api/web/NutrientViewer.html#.PrintMode).

## Using custom overlay items

Another approach to displaying arbitrary information on top of a PDF is the use of [custom overlay items](https://www.nutrient.io/guides/web/customizing-the-interface/creating-custom-overlay-items.md). This API allows you to place DOM nodes on top of the page.

In contrast to the [`RenderPageCallback`](https://www.nutrient.io/api/web/NutrientViewer.html#.RenderPageCallback) API, the custom overlay items are, as the name suggests, overlaid, so it’s still possible for your users to unmask the underlying image. Custom overlay items also require more bookkeeping if you want to place them on top of every page, and they won’t be included in the printed page.

For detailed information on how custom overlay items work, please refer to the [Creating Custom Overlay Items](https://www.nutrient.io/guides/web/customizing-the-interface/creating-custom-overlay-items.md) guide.
---

## Related pages

- [Find and convert PDF coordinates with JavaScript](/guides/web/pspdfkit-for-web/coordinate-spaces.md)
- [Rendering PDF pages in our JavaScript PDF viewer](/guides/web/features/rendering-pdf-pages.md)
- [View and edit PDF forms online](/guides/web/viewer/rendering/pdf-forms.md)
- [Render pages on canvas in our JavaScript PDF viewer](/guides/web/viewer/rendering/render-in-canvas.md)

