Back to homepage
Complex PDF Export with Embedded WOFF/WOFF2 Fonts
This pattern matches the browser addon flow: collect used webfont assets from the live DOM, convert non-TTF font files through fonteditor-core, and embed the result directly into the PDF.
Install
npm install @node-projects/layout2vector fonteditor-core
Code
import {
extractIRWithAssets,
renderIR,
PDFWriter
} from "@node-projects/layout2vector";
async function exportInvoicePdf(root) {
// includeFonts gathers the @font-face files used by extracted text.
const { ir, fontAssets } = await extractIRWithAssets(root, {
includeText: true,
includeImages: true,
includeFonts: true,
convertFormControls: true,
walkIframes: true
});
const writer = new PDFWriter({
pageWidth: 210,
pageHeight: 297,
fontAssets,
// Enables WOFF/WOFF2/OTF -> TTF conversion for embedding.
useFontEditorCore: true
});
const pdfDoc = await renderIR(ir, writer);
await pdfDoc.finalize();
const pdfBytes = pdfDoc.toBytes();
return pdfBytes;
}
function downloadPdf(bytes, filename = "layout-export.pdf") {
const blob = new Blob([bytes], { type: "application/pdf" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
Important: without useFontEditorCore: true, the PDF writer only embeds TTF sources and ignores WOFF/WOFF2/OTF sources.
Production notes
- Keep includeFonts enabled only when you need webfont fidelity to reduce network work.
- If the source app uses dynamic @font-face rules, wait for document fonts to load before calling extractIRWithAssets().
- This same approach works in browser extensions where fonts are loaded from page styles.