← dompdf.js Studio

DomPDF Constructor Options: The Complete Guide to format, margin, and scale

In dompdf.js, every PDF generation task begins with the DomPDF constructor. The constructor accepts a configuration object that establishes the document-wide defaults for page size, margins, and render scale — values that every subsequent addPage call inherits. Many developers habitually call new DomPDF() without arguments and only return to the documentation when the exported size is wrong, the margins are inconsistent, or the text looks soft. That wasted debugging time is entirely avoidable. This guide examines the three core constructor options — format, margin, and scale — in detail: their accepted types, sensible ranges, and how they interact with one another. We also clarify the precedence relationship between constructor defaults and per-page addPage options, then walk through best practices for invoices, reports, and certificates. Along the way we cover the traps that trip up real projects, from unit mismatches in margin strings to pagination drift caused by changing two options at once. By the end, you will know how to cover the full range of multi-page document requirements with the smallest possible configuration surface, and you will stop guessing at parameters entirely. We close with practical configuration recipes for common document types — invoices, reports, certificates, and business cards — so you can copy a proven starting point instead of deriving one from scratch, plus the verification habit that confirms a configuration before you trust it with real data. And because the constructor is where every document begins, we start there — with the decisions that shape every page that follows, and the traps that hide in plain sight.

Constructor Signature and Default Behavior

new DomPDF(options) takes an optional configuration object and returns an instance that represents the entire PDF document. Every configuration follows one guiding principle: the constructor establishes global defaults, and the addPage stage can override them on a per-page basis. This means you write format, margin, and scale exactly once in the constructor, and every subsequent page inherits those values automatically. You never repeat parameters per page, the code stays concise, and you avoid the layout drift that comes from pages configured with inconsistent values.

If you pass no arguments at all, DomPDF falls back to its built-in defaults. For the vast majority of generic scenarios — ordinary A4 documents, default margins, standard scaling — those defaults are perfectly adequate. But the moment you need print-quality output or fixed-size tickets and forms, you must configure explicitly. A practical habit is to maintain a single initialization function in your project that collects all common configuration in one place. Team members see the full picture at a glance, and adjusting a parameter later touches exactly one file.

Every field in the configuration object is optional, so you can set only what you need. Setting format without margin leaves the margins at their default; setting margin without format keeps the default A4 size. Understanding this per-field independence prevents configuration gaps. When output comes out at an unexpected size, you can quickly reason about which field you failed to set instead of guessing across the whole object, and debugging becomes a matter of minutes rather than hours.

One detail worth noting is that the constructor can be invoked again at any time, and separate instances never interfere with each other. If your page hosts several export entry points — a report section and an invoice section, say — create independent DomPDF instances for each. Configurations stay isolated, export results never cross-contaminate, and isolating instances per scenario is far safer than maintaining a shared global singleton. It also makes each export path independently testable, which pays off the first time one of them misbehaves.

format: Choosing the Right Page Size

The format option defines the PDF page size. A4 is the most common choice, and A3, A5, Letter, and Legal are also supported for documents with different physical requirements. Choose based on how the document will actually be consumed: contracts, invoices, and reports typically use A4; posters and foldouts use A3; tickets and labels use A5. A wrong size directly corrupts pagination results, so confirm the final print or reading medium during the requirements phase rather than after launch, when changes are expensive.

Beyond the standard sizes, some business scenarios need custom dimensions — business cards at 90x54mm, or non-standard certificate variants. You can achieve these by combining an @page rule inside the template with a fixed-width container: set the container width to match the target page width in CSS pixels (an A4 page is about 794px wide at 96 DPI), and dompdf.js paginates against the real content width. The output then matches the design file closely, with far better fidelity than coordinate-based drawing libraries.

One easily overlooked point: format defines the logical page size, but the actual output is also affected by scale and margin. Together, the three values determine the content area's width and height, and changing any one of them can push content that used to fit on one page onto a second. When debugging pagination, fix format and margin first, then adjust scale in isolation. Changing all three at once makes it impossible to tell which one caused the overflow, and you lose the ability to reproduce the problem deterministically.

It is also worth validating format together with your template's container width before you trust it. Create a test instance, export a sample containing a full-width table at the target size, and check whether anything overflows. This one-time verification exposes size-versus-template mismatches early, so they never surface on real production data, and it doubles as a reusable smoke test that any team member can run after template changes.

Complete Initialization Example

Here is a production-style initialization that sets document-wide defaults once and then lets pages inherit them. Notice that the per-page addPage call only overrides what genuinely differs; everything else falls back to the constructor values, keeping every page consistent by construction.

import { DomPDF } from 'dompdf.js';

// Constructor sets document-wide defaults once
const pdf = new DomPDF({
  format: 'A4',        // page size: A4
  margin: '20mm',      // margins: 20mm on all sides
  scale: 2,            // render scale: 2x for sharper text
});

// Every subsequent page inherits those defaults
pdf.addPage(invoiceHTML, { format: 'A4' });
pdf.addPage(attachmentHTML);  // no options: constructor defaults apply
pdf.save('invoice-2026-08.pdf');

margin: Setting Margins Without Surprises

The margin option controls the blank area around the page and accepts unit-bearing strings such as '20mm' or '15mm'. Margins are about far more than aesthetics: the content area equals the page size minus the margins on all four sides. Larger margins mean less content per page, pagination points move earlier, and long documents visibly grow in page count. When estimating page counts for quotes or contracts, factor margins in up front instead of being surprised at render time.

Treat margins as part of the layout system rather than a decorative afterthought. Line widths for headings and body text, and column widths for tables, should all be measured against the content area, not the full page width. A large share of layout accidents — overflowing tables, truncated text, elements spilling past the printable edge — trace back to content wider than the actual content area. Measure the content-area width in the browser before writing the template and most of those accidents simply disappear, saving hours of fiddling.

Margins also interact with headers and footers. When headers or footers are enabled, they typically live in the margin band, and overly small margins make the header visually collide with the body text — or get clipped when printed. Reserve enough margin space for the header and footer, and the document looks measurably more professional. A common recipe is slightly larger top and bottom margins than left and right, for example 25mm top and bottom with 20mm sides, which reads more balanced and survives printing more gracefully.

A subtle trap is inconsistent margin notation across the codebase. '20mm' and '2cm' are numerically equivalent, but mixing units hurts readability and invites copy-paste unit errors. Standardize on one unit — millimeters is a good default for print-oriented work — and centralize the values in constants so code review catches an anomalous margin at a glance. Consistency here is cheap now and prevents a class of layout bugs later.

scale: Balancing Fidelity and Performance

The scale option controls the render scale factor and directly affects output sharpness and render time. The default is adequate for the vast majority of documents. When a document demands high-fidelity printing or contains a lot of small text, raising scale makes text edges crisper and curves smoother, bringing the printed result closer to the design file. Certificates, posters, and other externally visible documents are the most common candidates for a higher scale.

But bigger is not automatically better. Each step up in scale increases the volume of data the WASM renderer must process, and both time and memory consumption rise accordingly. For long documents, an excessive scale can multiply export time, and the user experience degrades noticeably. Start from the default, test with real content, and only raise the factor when you can perceive a real difference in sharpness — then verify that the export duration remains acceptable before shipping.

Remember that scale, format, and margin jointly determine the content area, so treat the three as one tuning unit. Lock format and margin first to keep the layout stable, then use scale to fine-tune sharpness. Avoid adjusting multiple parameters simultaneously: when pagination breaks, you will not be able to tell which change caused it, the tuning process loses reproducibility, and you burn time that a disciplined one-variable-at-a-time approach would have saved.

When debugging sharpness, also watch the output file size. A larger scale legitimately produces a larger file, but if the file grows without any perceptible sharpness gain, the real culprit is oversized or duplicated images in the template. Optimize those resources instead of pushing scale higher — you get better results, smaller files, and faster exports all at once, which is the outcome the tuning process should actually be optimizing for.

Precedence Between Constructor and addPage Options

dompdf.js organizes options in two layers: the constructor sets global defaults, and addPage accepts per-page configuration. Precedence follows the nearest-value-wins rule — options passed to addPage override constructor defaults, while omitted fields continue to use the constructor values. This design allows a single multi-page document to mix page configurations freely: a cover page, body pages, and an appendix can each carry their own settings without interfering with one another.

A practical division of responsibilities keeps the code readable: put stable, document-wide settings (global margins, scale) in the constructor, and put page-specific settings (size, special margins) in the addPage call that needs them. With clear ownership at each layer, reading the export code reveals the document structure at a glance, and future maintenance touches only the layer that actually changes. Onboarding new team members becomes faster because the configuration story is consistent across the whole codebase.

One final caution: constructor configuration is fixed for the lifetime of the instance and does not change on its own. If your business produces multiple document specifications — A4 quotes alongside 90x54mm business cards — create a separate instance per specification instead of repeatedly overriding options on one shared instance. Separate instances keep state clean, allow each document type to be tested and reused in isolation, and ensure that a problem in one flow never leaks into another.

A concrete example ties the layering together: a typical invoice export configures A4 and 20mm margins in the constructor, passes only content to addPage, and builds the filename from the invoice number at save time. The whole export logic fits in ten lines yet spans template, configuration, and naming — exactly the separation of concerns the two-layer parameter design exists to provide, and a pattern you can copy to any document type.

A practical reference table helps teams pick sane starting points: invoices and reports default to A4 with 20mm margins; certificates often use A4 with a larger top margin to leave room for a seal; business cards use the 90x54mm custom-width technique described earlier; landscape posters and foldouts pair A3 with modest margins to maximize the printable area. Whatever your document type, start from a conservative configuration, export a sample, and adjust exactly one variable at a time until the result matches the design. Document the winning configuration next to the template so the next person does not have to rediscover it through trial and error. Over time, this table of proven configurations becomes the fastest onboarding artifact your team has, and the constructor stops being a mystery that each developer solves alone — it becomes a shared vocabulary everyone in the project speaks fluently.

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

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

Hello from dompdf.js!

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