Skip to content

Generate PDFs in the browser

Render an invoice or report in your web application with fullbleed/browser. The engine runs in a Web Worker and returns PDF bytes and optional PNG previews. Your application can download the result without a PDF server or service account.

Open the live starter Download the project

The starter includes a designed invoice and a three-page community report. Change the customer, reference, and ink color, or open Edit the HTML & CSS to paste your own template. Generate a preview, then download the actual PDF. All sample names, organizations, and amounts are fictional.

This guide uses npm package 0.3.0, wrapping Fullbleed engine 2.5.8. The browser and Node entries share the pinned engine and bundled fonts.

Run the starter

Extract the project ZIP. With Node.js 22.12 or newer, open a terminal in fullbleed-browser-starter and run:

npm ci
npm run dev

Open the localhost URL printed by Vite. The first render loads the engine and fonts from your development server. Document inputs are sent to the worker in the same browser; this starter does not upload them to a rendering service.

The HTML/CSS editor keeps changes in the tab until reload. To keep a template, edit src/invoice.html, src/invoice.css, src/report.html, or src/report.css in the downloaded project. The invoice uses {{customer}} and {{reference}} in HTML and {{ink}} in CSS; src/main.js fills those values and escapes text. Replace the fictional line items and calculations when building your application.

Add the browser SDK to an existing app

Install the package and copy its runtime into the directory your framework serves as static files:

npm install --save-exact fullbleed@0.3.0
npx fullbleed-browser-assets public/fullbleed

Import the browser entry in your client code:

import { createRenderer } from 'fullbleed/browser';

const renderer = createRenderer({ assetBaseUrl: '/fullbleed/' });
const result = await renderer.renderPdf({
  html: '<h1>Invoice NS-1042</h1><p>Consulting: USD 1,200.00</p>',
  css: '@page { size: A4; margin: 20mm } h1 { color: #175c52 }',
  previewDpi: 96,
  maxPages: 20,
  timeoutMs: 30_000,
});

const url = URL.createObjectURL(new Blob([result.pdf], { type: 'application/pdf' }));
const link = document.createElement('a');
link.href = url;
link.download = 'invoice.pdf';
link.click();
setTimeout(() => URL.revokeObjectURL(url), 60_000);

Run rendering from a user action and show loading, error, and cancellation states. The starter implements those states, clears outdated downloads after edits, and releases replaced preview URLs. Pass an AbortController's signal to renderPdf() to connect a Cancel button.

The asset-copy command verifies the installed runtime before writing it. Deploy the client, worker, engine, fonts, and notices together; repeat the copy when upgrading. A version mismatch returns a structured error.

Deploy a static site

Build the starter with:

npm run build

Upload the entire dist/ directory to a static host. The example uses relative asset paths and is checked under a nested URL prefix. For another application, set assetBaseUrl to its same-origin runtime directory, ending in /—for example, /my-app/fullbleed/.

Use HTTPS or localhost with Web Workers, WebAssembly, and Web Crypto available. The deployed site needs no Node process. The browser API guide covers content security policy, custom fonts and images, options, and errors.

Scope and verification

Use Fullbleed's supported print CSS. This API consumes static HTML/CSS; document scripts do not execute, and document URLs do not become browser fetches. Supply extra images and fonts as bytes through assets and fonts. Rendering a live website requires a different workflow.

Each call creates a fresh worker. Deadlines include startup and asset loading; completion or cancellation requests worker termination before the promise settles. Browsers do not expose a native thread-exit promise. Keep concurrent jobs bounded for the devices you support, especially when generating page previews.

The 0.3.0 release evidence retains checks in Chrome, Firefox, and Playwright WebKit, including PDF/PNG comparison with the installed Node package, independent PDF text checks, cancellation, damaged assets, and recovery. Playwright WebKit is not branded Safari certification. This browser API covers ordinary PDFs and previews; PDF/A, PDF/UA, PDF/X, and VDP are not exposed here.

For a server application, use the Node.js API or the Next.js download starter. For a quick experiment without installing a project, use the HTML/CSS playground.

For a React client application, use the React and TypeScript starter. It connects form changes to automatic PDF previews and includes a hook that cancels stale work and releases output URLs when inputs change or a component unmounts.