Table of Contents

Headers, Footers & Watermarks

Headers and Footers

PDF headers and footers are HTML snippets rendered by the engine's print header/footer layer. They appear on every page and support special tokens that are substituted with page metadata at render time.

Special Tokens

Token Replaced with
<span class='pageNumber'></span> Current page number
<span class='totalPages'></span> Total number of pages
<span class='date'></span> Current date
<span class='title'></span> Document title
<span class='url'></span> Page URL

Basic Example

string header = """
    <div style="font-size:10px; width:100%; text-align:center; font-family:sans-serif;">
        My Company — Confidential
    </div>
    """;

string footer = """
    <div style="font-size:10px; width:100%; text-align:center; font-family:sans-serif;">
        Page <span class='pageNumber'></span> of <span class='totalPages'></span>
    </div>
    """;

var pdf = await renderer
    .WithHeader(header)
    .WithFooter(footer)
    .RenderUrlAsPdfAsync("https://example.com");

From a File

Pass a file path instead of an HTML string — CobaltPdf detects path separators and reads the file automatically:

var pdf = await renderer
    .WithHeader("templates/header.html")
    .WithFooter("templates/footer.html")
    .RenderUrlAsPdfAsync("https://example.com");

Styling Notes

The header/footer engine has some quirks:

  • The template is rendered in a separate, narrow context. Use width:100% to span the full page.
  • External stylesheets and web fonts are not loaded. Use inline styles.
  • The default margin must be large enough to contain the header/footer — otherwise it will be clipped. Default margins are 1 cm; increase them if needed via WithMargins().
  • Background colors in headers/footers require -webkit-print-color-adjust: exact.
string colorHeader = """
    <div style="
        font-size:11px;
        width:100%;
        padding:4px 10px;
        background:#1a3c5e;
        color:white;
        -webkit-print-color-adjust:exact;
        font-family:Arial,sans-serif;">
        Acme Corp Internal Report — <span class='date'></span>
    </div>
    """;

Watermarks

Watermarks are HTML overlays injected into the page as a fixed-position div before the PDF is captured. They appear on every page because the overlay is position:fixed and Chromium repeats fixed elements across pages in print mode.

Use the WatermarkOptions.WithText factory method with a predefined WatermarkStyle for common watermark patterns:

using static CobaltPdf.Configuration.PdfOptions;

// One-liner — "DRAFT" in bold red, rotated -45 degrees
var pdf = await renderer
    .WithWatermark(WatermarkOptions.WithText("DRAFT", WatermarkStyle.RedDraft))
    .RenderUrlAsPdfAsync("https://example.com");

WatermarkStyle Presets

Style Appearance
SoftGray Light gray, 700 weight, -45 rotation, 0.28 opacity
RedDraft Bold red, 900 weight, -45 rotation, 0.30 opacity
Diagonal Dark gray, 600 weight, -45 rotation, 0.20 opacity
BoldStamp Dark centered stamp with border, no rotation, 0.28 opacity

Fluent Customization

Chain fluent helpers onto the factory result to fine-tune position, color, rotation, and opacity:

var pdf = await renderer
    .WithWatermark(
        WatermarkOptions.WithText("CONFIDENTIAL", WatermarkStyle.SoftGray)
                        .WithPosition(WatermarkPosition.TopRight)
                        .WithColor("#e74c3c")
                        .WithOpacity(0.2)
                        .WithRotation(-30))
    .RenderUrlAsPdfAsync("https://example.com");

WatermarkPosition

Value Placement
Center Centered both vertically and horizontally (default)
TopLeft Top-left corner
TopCenter Top edge, centered horizontally
TopRight Top-right corner
BottomLeft Bottom-left corner
BottomCenter Bottom edge, centered horizontally
BottomRight Bottom-right corner

Fluent Helpers Reference

Method Description
WithPosition(WatermarkPosition) Set position using a single enum value
WithColor(string cssColor) Override text color (any CSS value, e.g. "#ff0000", "red")
WithRotation(int degrees) Set rotation angle (-45 = counter-clockwise)
WithOpacity(double) Set opacity from 0.0 (invisible) to 1.0 (opaque)
WithHtml(string html) Replace generated HTML with a fully custom snippet
WithRasterize(bool enable = true) Flatten the watermark to an image baked into every page — see Rasterized watermarks

Custom HTML Watermark

For full control, pass raw HTML directly:

var pdf = await renderer
    .WithWatermark(new WatermarkOptions
    {
        Html       = "<div style='font-size:72pt; font-family:sans-serif; color:red;'>DRAFT</div>",
        Rotation   = -45,
        Opacity    = 0.15,
        Vertical   = VerticalAlignment.Middle,
        Horizontal = HorizontalAlignment.Center
    })
    .RenderUrlAsPdfAsync("https://example.com");

WatermarkOptions Properties

Property Type Default Description
Html string "" HTML markup rendered inside the watermark container
Rotation int 0 Rotation in degrees. Negative = counter-clockwise
Opacity double 0.5 0.0 = transparent, 1.0 = fully opaque
Vertical VerticalAlignment Middle Top, Middle, or Bottom
Horizontal HorizontalAlignment Center Left, Center, or Right
Color string? null CSS color override applied to all watermark text
Rasterize bool false Flatten the watermark to an image baked into every page — see Rasterized watermarks

Image Watermark

// Base64-encode a PNG and embed it directly
string base64Logo = Convert.ToBase64String(File.ReadAllBytes("logo.png"));

var pdf = await renderer
    .WithWatermark(new WatermarkOptions
    {
        Html     = $"<img src='data:image/png;base64,{base64Logo}' style='width:300px;' />",
        Rotation = 0,
        Opacity  = 0.1,
        Vertical = VerticalAlignment.Middle,
        Horizontal = HorizontalAlignment.Center
    })
    .RenderUrlAsPdfAsync("https://example.com");

Trial Watermark

When running without a valid license, CobaltPdf automatically overlays a COBALT PDF TRIAL watermark on every page. Activate a license to remove it — see Licensing.

The trial watermark and any user-defined watermark can coexist; user watermarks are rendered on top.


Rasterized watermarks

By default, watermarks are injected as selectable text/vector content — which means anyone with a PDF editor can select the watermark text and delete it. The opt-in WatermarkOptions.Rasterize property (fluent: .WithRasterize(bool enable = true)) flattens the watermark to a high-resolution image baked into every page instead, so it can't be removed with a PDF editor's "edit text → delete".

var pdf = await renderer
    .WithWatermark(
        WatermarkOptions.WithText("CONFIDENTIAL", WatermarkStyle.SoftGray)
                        .WithRotation(-45)
                        .WithOpacity(0.3)
                        .WithRasterize())
    .RenderUrlAsPdfAsync("https://example.com");

The default is false — existing watermark behaviour is completely unchanged unless you opt in. The flag and behaviour are identical in both the Chromium (CobaltPDF) and WebKit (CobaltPDF.WebKit) libraries.

Important

Rasterization is tamper-resistance, not DRM. A baked-in image is much harder to remove than selectable text, but a determined user can still crop or paint over page pixels. Do not rely on it as an unremovable mark.