How to watermark a PDF
- Drop your PDF into the zone above, or click to browse.
- Type the watermark text — common choices are CONFIDENTIAL, DRAFT, DO NOT COPY, or your company name.
- Choose a colour (Gray, Red, Blue, or Black), size (Small / Medium / Large), and opacity. The opacity slider controls how transparent the watermark is — lower values keep page content more readable underneath.
- Click Apply & download. The watermarked PDF saves to your device.
Everything runs in your browser using pdf-lib. No file is sent to a server — open DevTools (F12) → Network while applying to confirm zero uploads.
When to watermark a PDF
- Sharing a draft for review — stamp DRAFT so recipients know the document is not final and should not be distributed further.
- Sending a confidential document — CONFIDENTIAL or PRIVATE acts as a visible reminder that the content is not for public circulation.
- Distributing a proof for approval — PROOF or FOR APPROVAL signals that the document requires sign-off before use.
- Marking a document as superseded — SUPERSEDED or VOID prevents an outdated version from being acted on if it resurfaces.
- Branding shared documents — add a company name or URL as a watermark to PDFs shared publicly, so the source is clear if the file is redistributed.
- Internal distribution control — INTERNAL USE ONLY marks documents that should not leave the organisation.
How it works under the hood
PDF pages contain a content stream — a sequence of drawing instructions that render text, images, and vector graphics. pdf-lib appends additional drawing instructions to each page's content stream to stamp the watermark text.
The text is drawn using Helvetica, one of the 14 standard PDF fonts that every viewer includes without needing the font embedded in the file. This keeps the output file size nearly identical to the input — typically only a few kilobytes larger per page.
The watermark is placed at the centre of each page and rotated 45°. pdf-lib's drawText method accepts a rotate parameter that applies a rotation transform around the text's anchor point. The font width at the chosen size is calculated first (font.widthOfTextAtSize), so the text is centred accurately before rotation.
The opacity value is applied using the PDF graphics state — pdf-lib sets the fill opacity for that drawing operation only, leaving the rest of the page content at full opacity. This is why page content remains readable through the watermark rather than the entire page becoming translucent.
For pages that differ from standard A4 dimensions (e.g. US Letter, or custom sizes), the font size is scaled proportionally to the page diagonal so the watermark fills approximately the same visual proportion regardless of page size.
Limits and what to expect
- The watermark cannot be cleanly removed — it is drawn as content on each page, not stored as a separate layer. Keep the original unwatermarked file if you need to produce clean copies.
- Text length: the tool accepts up to 40 characters. Very long strings may extend slightly beyond the page edges at larger sizes — use a shorter text or the Small size for long labels.
- All pages are watermarked: the tool applies the watermark to every page. To target specific pages, use Split PDF to extract them, watermark separately, then Merge PDF to recombine.
- Password-protected PDFs: the tool attempts to load encrypted PDFs using the
ignoreEncryptionflag. PDFs that require a password to view their content will fail — unlock them first. - Browser support: Chrome 90+, Firefox 90+, Safari 15+, Edge 90+.
Privacy: what happens to your file
Your PDF is read into browser memory, modified locally by pdf-lib, and downloaded directly to your device. Nothing is sent to a server. The watermarking operation happens entirely within the browser tab — open the Network tab in DevTools while applying to see zero outbound requests.
This matters particularly when the document being watermarked is itself sensitive. Confidential contracts, financial reports, and legal filings should not need to pass through a third-party server just to have the word "CONFIDENTIAL" added to them. With keptlocal, they do not.