← dompdf.js Studio

PDF Watermark Guide: Text & Image Watermarks with dompdf.js

Internal documents, contract drafts, and design previews almost always need watermarks: marking a confidentiality level, discouraging screenshot leaks, or asserting copyright ownership. The traditional path is either paid desktop tools that process files one at a time, or heavy server-side PDF libraries that add latency and infrastructure. dompdf.js makes watermarking a pure frontend concern. Because it renders the DOM directly, a watermark is just an HTML element styled with CSS — a rotated text layer, a tiled background pattern, or an image stamp with controlled opacity. Combined with automatic pagination, the watermark repeats consistently on every page of a multi-page document, so a 20-page report gets uniform protection without 20 manual insertions. This guide walks through the scenarios, the implementation techniques, complete code examples, multi-page consistency handling, and the practical gotchas you need to know before shipping watermarked PDFs, ending with a troubleshooting checklist that covers the most common failure modes. Watermarking is one of those features that looks trivial on the surface and rewards careful design underneath: the difference between a professional mark and a messy overlay is a handful of CSS decisions. The recipes here are designed to be copied into your own templates with minimal adaptation, and each section ends with the specific decisions that matter most for that technique.

Watermark Use Cases and Requirements

Watermark scenarios fall into three broad groups. Confidential-document marking flags internal material with labels such as 'Internal Only' or 'Confidential'. Copyright protection prevents design drafts and mockups from being repurposed without permission. Customer personalization stamps preview PDFs with a recipient's name and date, deterring free-tier users from redistributing your work. Each group needs a slightly different treatment.

Watermark requirements are often decided late in the project, after the export feature is already built. That is a mistake: retrofitting watermarks means touching every template and re-testing every page type. Decide the rules in the requirements phase — who gets watermarks, what text they carry, how transparent they are, and whether they change per user — and the implementation stays a small, clean addition instead of a refactor.

Each scenario imposes different requirements. Confidential labels must be visible without obscuring the body text. Copyright marks should be hard to crop out and consistent across pages. Personalized watermarks are generated dynamically — every user's PDF carries different text, which means the watermark must be injected at render time rather than baked into a template that was prepared in advance.

There is also the question of single-page versus multi-page documents. Watermarking only the first page leaves the rest of a document exposed, because anyone can screenshot the later pages and bypass the protection entirely. With dompdf.js, a fixed-position watermark layer repeats on every page automatically, so a 20-page report gets uniform protection without 20 manual insertions and without any gaps a leaker could exploit.

Beyond the three main groups, there are secondary use cases worth planning for: draft marking for internal review cycles, batch identifiers for bulk-sent mailings, and brand stamps on white-label exports. Each is a variation of the same technique, but each benefits from a naming and configuration convention so that watermark text and style stay consistent across the product rather than drifting template by template.

Requirements also interact with the data model. If watermarks change per user, the export function needs access to the current user's name, department, and timestamp at render time — which means watermark data should flow through the same context object as the document content. Designing that plumbing once, at the start, avoids sprinkling user-lookup code through every export path later and keeps the feature consistent everywhere it is used.

Implementing Text Watermarks

Since dompdf.js renders ordinary HTML, a text watermark is simply an absolutely positioned element. Place a div in the middle of the page, rotate it with transform: rotate(-45deg), and you have the classic diagonal watermark that appears across the document like a security pattern — spanning the whole page and hard to crop out cleanly.

Opacity is the key control. Keep it between 0.1 and 0.2: too low and the mark is invisible to anyone skimming the document; too high and it competes with the content for attention. A low-contrast gray such as #999 reads as a mark rather than as content, striking the right balance between warning effect and readability.

One honest caveat: text watermarks in dompdf.js are rendered as vector text, which means they are selectable and copyable. That is an advantage for clarity but a limitation for anti-tampering — a determined technical user can extract the watermark text. For true leak prevention on highly sensitive documents, combine watermarking with server-side encryption or PDF permission restrictions rather than relying on the frontend alone.

Layering is a simple trick that makes watermarks noticeably more robust. Combine a large diagonal text mark with a fine tiled pattern, or add the date and the username in a second line. Each layer makes cropping or removing the mark harder, and because the layers are just HTML elements, the combinations are limited only by your CSS skills.

Choosing the right position for the diagonal mark is a small design decision with visible consequences. Centered marks are the classic choice and work for most documents; corner marks are less intrusive for content-heavy pages; a bottom band works well for draft labels. Since the position is just CSS, test two or three variants on a real page before settling — the difference in perceived professionalism is surprisingly large.

For multi-language documents, remember that the watermark text itself follows the same font rules as the body. Chinese watermark text renders with the bundled Source Han Sans SC automatically, so a bilingual mark such as '机密 · Confidential' works without any extra font configuration — one more place where the zero-configuration design removes friction that other libraries would introduce here.

There is also a layout interaction to check: a large rotated mark can overlap headings or table headers on dense pages. If the watermark sits above content that must stay readable, either reduce the font size of the mark, raise its transparency, or shift the rotation angle slightly. A quick visual pass on the densest page of the document settles whether the balance is right.

Code Example: Diagonal and Tiled Watermarks

import { DomPDF } from 'dompdf.js';

const watermarkHTML = `
  <style>
    @page { margin: 20mm; }
    .watermark {
      position: fixed;
      top: 45%; left: 0; right: 0;
      text-align: center;
      font-size: 48px;
      color: #999;
      opacity: 0.12;
      transform: rotate(-45deg);
      pointer-events: none;
    }
    .tiled {
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: repeating-linear-gradient(
        -45deg,
        transparent 0 60px,
        rgba(153,153,153,0.10) 60px 120px
      );
    }
  </style>
  <!-- Diagonal text watermark + tiled diagonal stripes: double protection -->
  <div class="watermark">机密 · 内部资料</div>
  <div class="tiled"></div>
  <h1>Product Requirements Doc v2.3</h1>
  <p>Internal use only. Do not distribute outside the team.</p>`;

const pdf = new DomPDF();
pdf.addPage(watermarkHTML, { format: 'A4' });
pdf.save('prd-watermarked.pdf');

Image Watermarks and Multi-Page Consistency

Image watermarks suit logos and anti-forgery stamps. Place a transparent PNG inside an absolutely positioned layer using an <img> tag or a background-image, set the opacity, and you have a branded watermark. The technique is identical to the text version — only the element changes, so there is no new learning curve.

Using position: fixed is what makes watermarks repeat across pages. The watermark layer is anchored to the page viewport rather than the content flow, so when dompdf.js paginates the document, the layer is redrawn on every page. No per-page insertion logic is required, and the watermark cannot silently disappear when the page count changes.

For documents assembled from multiple addPage calls, factor the watermark markup into a reusable template string and concatenate it into each page's HTML. That keeps the style consistent across every page while leaving the body content free to vary, and a single change propagates everywhere — easy to maintain and hard to get wrong.

Watermarks can also be dynamic: stamp the export timestamp, the operator's account, or even a per-download random token into the watermark text at render time. Because the watermark is injected while building the HTML string, dynamic values cost almost nothing to implement, yet they give you per-file traceability that static watermarks cannot provide.

When using image watermarks, pay attention to the source asset quality. A low-resolution logo stretched across a page looks pixelated and undermines the document's credibility, so export the watermark asset at the size it will actually be displayed and keep a transparent PNG version specifically for this purpose. The same asset can then be reused in headers, footers, and watermark layers without surprises.

Multi-page consistency also depends on how you assemble the document. If you build pages from a shared layout function, put the watermark markup in that function so every page inherits it by construction; if pages are assembled ad hoc, a post-processing pass that injects the watermark into each page's HTML is a reliable alternative. Either way, the rule is the same: the watermark belongs to the page shell, not to individual content blocks.

If you need different watermarks on different pages of the same document — for example, 'Draft' on early pages and 'Final' on the last — build the page loop so the watermark string is a variable passed into each page's template. Because the watermark is just template data, conditional marks cost nothing extra, and the page shell stays a single function.

Watermark Design Best Practices

Always set pointer-events: none on watermark layers so they never interfere with interaction or layout, and use z-index to keep the mark above the content while its low opacity keeps it out of the reader's way. Without pointer-events disabled, invisible layers can swallow clicks in the live page and produce confusing behavior for users.

A rotation angle between 30 and 45 degrees balances legibility and aesthetics. For tiled patterns, keep the spacing even. For personalized marks, include the date and the recipient's name or ID so every leaked file can be traced back to a specific person — the traceability itself is part of the deterrent.

Validate watermarks against real business content, not demo text. Long titles, dense tables, and image-heavy pages change how the mark sits visually and how much of the page it covers. Running a real-data sample before release catches positioning and density problems that never appear in a clean demo document.

Security teams often ask whether watermarks can be removed. The honest answer is that a determined attacker can remove any visible watermark. The value of watermarking is deterrence and traceability — making leaks identifiable and risky — not mathematical impossibility. Pair it with access controls and treat it as one layer in a defense-in-depth strategy.

Check for overlap between the watermark and headers, footers, or page numbers — overlapping marks look sloppy. Finally, verify the opacity and position on a real A4 preview before shipping; perceived transparency varies noticeably across displays and printers, so a printed sample is the only reliable way to confirm the final look.

Accessibility is an easy point to overlook. Watermark layers should be hidden from screen readers and excluded from the tab order on the live page, since they carry no information for assistive technology and can confuse users navigating by keyboard. In the PDF itself, keep the opacity low enough that the mark never interferes with reading the content, and remember that a watermark is a signal, not a content layer.

Frequently Asked Questions

Q: The watermark only appears on the first page? A: Check whether the watermark layer uses position: fixed. If it sits in normal flow, pagination will cut it off; switching to fixed makes the engine repeat it on every page. This is by far the most common watermark bug.

Q: Can people copy the watermark text out of the PDF? A: Yes — dompdf.js outputs vector text, so watermark text is technically extractable. For copy protection, combine watermarks with PDF permission flags or server-side encryption; the frontend approach is best for deterring visual leaks, so position it accordingly.

Q: The watermark is too faint or too dark? A: Adjust opacity and color. Start around 0.1-0.15 and validate on a printed sample, since screens flatter transparency compared to paper — the difference between screen and print is larger than most people expect.

Q: The image watermark shows a white background? A: Use a PNG with an alpha channel. JPG files have no transparency and will render as a solid rectangle, which ruins the effect on colored or textured document backgrounds.

Q: Can I watermark only selected pages? A: Yes. Since each addPage call renders its own content, simply include the watermark markup in the pages that need it and omit it from the rest. This gives you per-page control that server-side watermark tools usually charge extra for.

Q: Do watermarks survive printing? A: Yes, and that is the point — the watermark is part of the page content, so it prints along with everything else. Test once on a physical printer, because screen and paper differ more than people expect, especially for low-opacity gray marks.

Q: Does the watermark increase the file size? A: Text watermarks are vector text and add virtually nothing; tiled backgrounds are just a few gradient commands. Only high-resolution image watermarks add noticeable bytes, and even those are modest.

One question that comes up in security reviews is whether watermarks can deter screenshots taken on the reader's own device. No client-side watermark can fully prevent that, but personalized marks make the leak traceable, and a visible label makes careless sharing less likely in the first place. Combined with access logs, even simple watermarks measurably reduce casual leaks — the goal is deterrence, not cryptography, and the two should never be confused.

⚡ 现场演示(点击生成 PDF)

下面的按钮用 dompdf.js 在浏览器端实时生成 PDF,无需后端:

Hello from dompdf.js!

这是由 dompdf.js 渲染的示例 PDF 内容。