Node.js SDKFirst PDF · 5 min

Node.js SDK quickstart

Create the client explicitly, provide final HTML or a cloud template, and choose Buffer, stream, file, or background delivery.

Install the package

Terminal
bash
 1npm install @bladepdf/node

Create the client

The SDK never reads .env. Read the secret through your application configuration and pass it explicitly.

render.ts
typescript
 1import { BladePdf } from '@bladepdf/node';
 2
 3const apiKey = process.env.BLADEPDF_API_KEY;
 4
 5if (!apiKey) {
 6  throw new Error('Missing BLADEPDF_API_KEY');
 7}
 8
 9const bladePdf = new BladePdf({ apiKey });

Render raw HTML

Buffered render
typescript
 1const result = await bladePdf
 2  .fromHtml('<h1>Invoice INV-42</h1>')
 3  .format('A4')
 4  .printBackground()
 5  .render();
 6
 7result.pdf; // Buffer
 8await result.save('invoice.pdf');
 9console.log(result.requestId);

Use EJS, Handlebars, React SSR, or another engine

Render templates in your application. BladePDF receives completed HTML and does not need to know which engine produced it. Handlebars compile() output and React renderToStaticMarkup() output are passed to fromHtml() in exactly the same way as this EJS example.

Pre-rendered EJS
typescript
 1import ejs from 'ejs';
 2
 3const html = await ejs.renderFile('invoice.ejs', { invoice });
 4
 5const result = await bladePdf
 6  .fromHtml(html, { baseDirectory: '/srv/app/templates/invoice' })
 7  .render();

Allow local assets

Without configured roots, automatic resolution does not read the filesystem. Recreate the client with explicit permissions when HTML references local files.

Filesystem permissions
typescript
 1const bladePdf = new BladePdf({
 2  apiKey,
 3  assets: {
 4    documentRoot: '/srv/app/public',
 5    searchRoots: ['/srv/app/public', '/srv/app/storage'],
 6    localHosts: ['localhost', 'app.example.test'],
 7  },
 8});

Stream a large PDF

Node stream
typescript
 1import { pipeline } from 'node:stream/promises';
 2
 3const result = await bladePdf.fromHtml(html).renderStream();
 4
 5await pipeline(result.stream, httpResponse);

A returned stream is one-shot. Always consume or destroy it. Use renderToFile() when the destination is a local file and you want safe temporary-file handling.

Submit a background stored render

Background render
typescript
 1const submission = await bladePdf
 2  .fromTemplate('invoice.standard', { invoice })
 3  .reference('INV-42')
 4  .storePdf()
 5  .webhook({
 6    url: 'https://example.test/webhooks/bladepdf',
 7    secret: webhookSecret,
 8  })
 9  .submit();
10
11console.log(submission.requestId);
JavaScript and SVG scope

A file referenced by <script src> or an external SVG URL is uploaded. The resolver does not inspect JavaScript imports, dynamic imports, fetch(), runtime URLs, SVG contents, or dependencies embedded in SVG.