Generate PDFs in Vue¶
Connect a Vue form to a PDF preview with fullbleed/browser. Change a field
or an HTML/CSS template and the actual PDF updates after a short pause. This
starter renders in a browser worker and needs no PDF server or account.
Open the Vue demo Edit source online Download the Vue project
The project includes a designed invoice, a three-page report, a Vue form and template editor, and a reusable TypeScript composable. Sample names, records, and amounts are fictional. The code is MIT licensed, including commercial use.
Edit the project online¶
Choose Edit source online, then Open in StackBlitz to load the complete project without a local Node.js installation. Wait for Ready in the preview, change the customer, and choose Download PDF after the preview updates.
Open src/DocumentEditor.vue in the Files panel to change the Vue form.
Edit src/invoice.html and src/invoice.css to change the print layout.
Saving a print-template file reloads the document component and resets its
form values and temporary editor changes.
The online launcher submits the same source files and lockfile as the ZIP.
It opens a temporary project; save or export changes in StackBlitz to keep them.
Run the project locally¶
Extract the ZIP. With Node.js 22.12 or newer, open a terminal in
fullbleed-vue-starter and run:
Open the localhost URL printed by Vite. Edit the customer, reference, or ink color and wait for Ready, then choose Download PDF. Turn off Update automatically to generate on demand. Cancel stops a pending preview or active render. Close editor releases its resources; reopening starts fresh.
The lockfile pins Fullbleed npm 0.3.1 / engine 2.5.10, Vue 3.5.43,
TypeScript 6.0.3, and Vite 8.3.2. The build downloads the published
dependencies and copies their verified runtime. TypeScript 6 is pinned for
compatibility with the project's vue-tsc type checker.
Customize the document¶
Expand Edit the HTML & CSS to paste a print template. These edits stay in the tab until reload or closing the editor. Keep a layout in the source files:
| File | Purpose |
|---|---|
src/DocumentEditor.vue |
Form fields, template state, validation, and preview UI |
src/usePdfPreview.ts |
Reactive rendering, cancellation, stale-result protection, and URL cleanup |
src/App.vue |
Application shell and editor mount/unmount |
src/invoice.html / src/invoice.css |
Invoice print layout |
src/report.html / src/report.css |
Three-page report print layout |
src/style.css |
Application interface |
The invoice fills {{customer}} and {{reference}} in HTML and {{ink}} in CSS.
The app escapes customer text before inserting it and validates the hex color.
Line items, totals, addresses, and dates are fixed samples: replace them with
your data and calculations.
Print templates are separate from Vue component templates. Fullbleed consumes
static HTML/CSS and does not capture the Vue page. Use
supported print CSS. Document scripts do not execute, and
document URLs do not fetch remote resources. Pass extra font or image bytes
through the SDK's fonts and assets options.
Reuse the composable in an existing Vue app¶
Install the package and copy its runtime into your static directory:
Copy src/usePdfPreview.ts from the project. Call it during component setup
with a computed input or a getter that reads reactive values:
<script setup lang="ts">
import { computed } from 'vue';
import { usePdfPreview } from './usePdfPreview';
const props = defineProps<{ html: string; css: string }>();
const input = computed(() => ({
html: props.html, css: props.css,
previewDpi: 96, maxPages: 20, timeoutMs: 30_000,
}));
const { status, result, error, generate, cancel } = usePdfPreview(input, '/fullbleed/');
</script>
<template>
<section>
<button @click="generate">Generate PDF</button>
<button @click="cancel">Cancel</button>
<p role="status">{{ error?.message ?? status }}</p>
<template v-if="result">
<a :href="result.url" download="document.pdf">Download PDF</a>
<img v-for="(url, index) in result.previews" :key="url"
:src="url" :alt="`PDF page ${index + 1}`" />
</template>
</section>
</template>
The returned values are refs and can be destructured. For a ref containing an input object, replace the object when changing it; the composable does not deeply watch font or asset arrays.
Its default delay is 450 ms. Set { auto: false } to generate only on demand,
or pass a boolean ref as auto to switch modes. { delayMs: 800 } waits longer
after edits. Cancel stops work until the next input change or generate() call.
Changing preview mode also resets output.
The watcher invalidates downloads synchronously, aborts superseded work, and
ignores obsolete results. Replaced PDF/PNG Blob URLs are revoked. Rendering
starts after mount; scope disposal stops the watcher and releases its resources.
See Vue's composable lifecycle guidance.
Use it in a browser component. This example does not handle server rendering
or KeepAlive deactivation.
Build and deploy¶
Upload the entire dist/ directory to a static HTTPS host. Relative paths
support nested deployment URLs. In another app, set the composable's asset URL
to your same-origin runtime directory, ending in /. Deploy the client, worker,
engine, fonts, manifest, and notices together.
The deployed app needs no Node process. Its first render loads the engine and fonts; document inputs stay in that browser. It needs HTTPS or localhost, Web Workers, WebAssembly, and Web Crypto. The browser SDK guide covers hosting, custom assets, and API limits.
What is checked¶
The source workflow builds and checks the project in Chrome, Firefox, and Playwright WebKit. It downloads real PDFs, independently checks their text and page sizes, and compares default PDF and preview bytes with the installed Node package. It exercises fast edits, both preview modes, cancellation, runtime-outage recovery, template editing, unmount/remount, URL cleanup, and 1440/390/320px layouts. The docs build installs and checks the exact downloadable ZIP.
These fixtures do not establish compatibility with every device or hosting policy. WebKit testing is not branded Safari certification. Worker counts observe browser API handles, not native thread-exit events. Bound concurrent instances for the devices you support.
This browser entry provides ordinary PDFs and previews. It does not expose PDF/A, PDF/UA, PDF/X, or VDP options. For React, use the React PDF starter.