{"_id":"@alessiofrittoli/html-to-pdf","_rev":"3-b7c76c5b2e2de3f9715953b85ee3ce47","name":"@alessiofrittoli/html-to-pdf","dist-tags":{"alpha":"1.0.0-alpha.1","latest":"1.1.0"},"versions":{"1.0.0-alpha.1":{"name":"@alessiofrittoli/html-to-pdf","version":"1.0.0-alpha.1","keywords":["nodejs","npm","pdf"],"author":{"url":"https://alessiofrittoli.it","name":"Alessio Frittoli","email":"info@alessiofrittoli.it"},"license":"MIT","_id":"@alessiofrittoli/html-to-pdf@1.0.0-alpha.1","maintainers":[{"name":"alessiofrittoli","email":"info@alessiofrittoli.it"}],"homepage":"https://github.com/alessiofrittoli/html-to-pdf#readme","bugs":{"url":"https://github.com/alessiofrittoli/html-to-pdf/issues","email":"info@alessiofrittoli.it"},"dist":{"shasum":"25e1f28d72fab817e0a48c747cf8a071e7b0a19e","tarball":"https://registry.npmjs.org/@alessiofrittoli/html-to-pdf/-/html-to-pdf-1.0.0-alpha.1.tgz","fileCount":7,"integrity":"sha512-du3Wd7awmT7lNzgJtapAQBugnZrZAGalWnf3kjk63COTB7H0E0saLqN8zqLZvRWYzmLd53kCwCwpsj8F+Pn2yg==","signatures":[{"sig":"MEQCIFc5zmN3Ei8dPvCU0UL7N2LzEAJhe27vp0VlH9pCS0WxAiBJPDHWjuhUobvIxipBlVI7AkKVb9i6nc3pOPaudVNm6Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18267},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","funding":[{"url":"https://github.com/sponsors/alessiofrittoli","type":"github"}],"gitHead":"624cc046c66b3081eb66e90cd95280fe5605feea","scripts":{"dev":"cross-env NODE_ENV=development tsup --watch","//1a":"*********************************************************************","//1b":"******************** DEV - BUILD - LINT - RELEASE *******************","//1c":"*********************************************************************","//2a":"*********************************************************************","//2b":"***************************** UNIT TESTS ****************************","//2c":"*********************************************************************","//3a":"*********************************************************************","//3b":"************************ UNIT TESTS COVERAGE ************************","//3c":"*********************************************************************","lint":"eslint","test":"jest --verbose","build":"pnpm lint && pnpm test:ci && pnpm build:prod","release":"node scripts/release.js --verbose --npm","test:ci":"jest --ci --verbose","build:prod":"cross-env NODE_ENV=production tsup","test:watch":"jest --watchAll --verbose","test:coverage":"pnpm test:watch --coverage","test:coverage:ci":"pnpm test:ci --coverage","test:coverage:serve":"concurrently --prefix none --kill-others \"pnpm test:coverage\" \"pnpm test:serve-coverage\"","test:serve-coverage":"http-server ./coverage/lcov-report --gzip true -p 0 -o --silent"},"_npmUser":{"name":"alessiofrittoli","email":"info@alessiofrittoli.it"},"repository":{"url":"git+https://github.com/alessiofrittoli/html-to-pdf.git","type":"git"},"_npmVersion":"11.7.0","description":"Easily convert HTML to PDF","directories":{},"sideEffects":false,"_nodeVersion":"22.15.0","dependencies":{"puppeteer":"^24.34.0","bufferutil":"^4.1.0","inline-css":"^4.0.3","@alessiofrittoli/url-utils":"^3.7.1","@alessiofrittoli/crypto-buffer":"^3.9.0","@alessiofrittoli/stream-reader":"^2.6.1"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","tsup":"^8.5.1","dotenv":"^17.2.3","eslint":"^9.39.2","globals":"^16.5.0","ts-jest":"^29.4.6","ts-node":"^10.9.2","cross-env":"^10.1.0","@eslint/js":"^9.39.2","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^25.0.3","http-server":"^14.1.1","concurrently":"^9.2.1","@jest/globals":"^30.2.0","@types/inline-css":"^3.0.4","typescript-eslint":"^8.50.0","@alessiofrittoli/node-scripts":"3.3.0","@alessiofrittoli/stream-writer":"^1.4.0"},"_npmOperationalInternal":{"tmp":"tmp/html-to-pdf_1.0.0-alpha.1_1766343081006_0.38985656192129325","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@alessiofrittoli/html-to-pdf","version":"1.0.0","keywords":["nodejs","npm","pdf"],"author":{"url":"https://alessiofrittoli.it","name":"Alessio Frittoli","email":"info@alessiofrittoli.it"},"license":"MIT","_id":"@alessiofrittoli/html-to-pdf@1.0.0","maintainers":[{"name":"alessiofrittoli","email":"info@alessiofrittoli.it"}],"homepage":"https://github.com/alessiofrittoli/html-to-pdf#readme","bugs":{"url":"https://github.com/alessiofrittoli/html-to-pdf/issues","email":"info@alessiofrittoli.it"},"dist":{"shasum":"aa0224586033d3d59c011dff90f6fabedad8d44c","tarball":"https://registry.npmjs.org/@alessiofrittoli/html-to-pdf/-/html-to-pdf-1.0.0.tgz","fileCount":7,"integrity":"sha512-LWltDcJsDXYpmx8F+1pHYWBPYh3YOYXaL/kTVXqSadgwGxfDIJTmbtDYaOEjdOATmQo/1Q2ZobyMS65p6Y3XPQ==","signatures":[{"sig":"MEUCIF6B2z0QABrT3sQxQFIQr7ZYOKYImHwhHYoHUVG29ZqyAiEA8J3KUsoYr1ruWSWnqmMPVCVTu3CGauQEO5soQajxkqo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18259},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","funding":[{"url":"https://github.com/sponsors/alessiofrittoli","type":"github"}],"gitHead":"5099c97595048e0aaab8480125df0508012b16d8","scripts":{"dev":"cross-env NODE_ENV=development tsup --watch","//1a":"*********************************************************************","//1b":"******************** DEV - BUILD - LINT - RELEASE *******************","//1c":"*********************************************************************","//2a":"*********************************************************************","//2b":"***************************** UNIT TESTS ****************************","//2c":"*********************************************************************","//3a":"*********************************************************************","//3b":"************************ UNIT TESTS COVERAGE ************************","//3c":"*********************************************************************","lint":"eslint","test":"jest --verbose","build":"pnpm lint && pnpm test:ci && pnpm build:prod","release":"node scripts/release.js --verbose --npm","test:ci":"jest --ci --verbose","build:prod":"cross-env NODE_ENV=production tsup","test:watch":"jest --watchAll --verbose","test:coverage":"pnpm test:watch --coverage","test:coverage:ci":"pnpm test:ci --coverage","test:coverage:serve":"concurrently --prefix none --kill-others \"pnpm test:coverage\" \"pnpm test:serve-coverage\"","test:serve-coverage":"http-server ./coverage/lcov-report --gzip true -p 0 -o --silent"},"_npmUser":{"name":"alessiofrittoli","email":"info@alessiofrittoli.it"},"repository":{"url":"git+https://github.com/alessiofrittoli/html-to-pdf.git","type":"git"},"_npmVersion":"11.7.0","description":"Easily convert HTML to PDF","directories":{},"sideEffects":false,"_nodeVersion":"22.15.0","dependencies":{"puppeteer":"^24.34.0","bufferutil":"^4.1.0","inline-css":"^4.0.3","@alessiofrittoli/url-utils":"^3.7.1","@alessiofrittoli/crypto-buffer":"^3.9.0","@alessiofrittoli/stream-reader":"^2.6.1"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","tsup":"^8.5.1","dotenv":"^17.2.3","eslint":"^9.39.2","globals":"^16.5.0","ts-jest":"^29.4.6","ts-node":"^10.9.2","cross-env":"^10.1.0","@eslint/js":"^9.39.2","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^25.0.3","http-server":"^14.1.1","concurrently":"^9.2.1","@jest/globals":"^30.2.0","@types/inline-css":"^3.0.4","typescript-eslint":"^8.50.0","@alessiofrittoli/node-scripts":"3.3.0","@alessiofrittoli/stream-writer":"^1.4.0"},"_npmOperationalInternal":{"tmp":"tmp/html-to-pdf_1.0.0_1766343391428_0.1991150445905514","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@alessiofrittoli/html-to-pdf","version":"1.1.0","description":"Easily convert HTML to PDF","author":{"name":"Alessio Frittoli","email":"info@alessiofrittoli.it","url":"https://alessiofrittoli.it"},"license":"MIT","funding":[{"type":"github","url":"https://github.com/sponsors/alessiofrittoli"}],"keywords":["nodejs","npm","pdf"],"homepage":"https://github.com/alessiofrittoli/html-to-pdf#readme","bugs":{"url":"https://github.com/alessiofrittoli/html-to-pdf/issues","email":"info@alessiofrittoli.it"},"repository":{"type":"git","url":"git+https://github.com/alessiofrittoli/html-to-pdf.git"},"main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","sideEffects":false,"scripts":{"//1a":"*********************************************************************","//1b":"******************** DEV - BUILD - LINT - RELEASE *******************","//1c":"*********************************************************************","dev":"cross-env NODE_ENV=development tsup --watch","build:prod":"cross-env NODE_ENV=production tsup","build":"pnpm lint && pnpm test:ci && pnpm build:prod","lint":"eslint","release":"node scripts/release.js --verbose --npm","//2a":"*********************************************************************","//2b":"***************************** UNIT TESTS ****************************","//2c":"*********************************************************************","test":"jest --verbose","test:watch":"jest --watchAll --verbose","test:ci":"jest --ci --verbose","//3a":"*********************************************************************","//3b":"************************ UNIT TESTS COVERAGE ************************","//3c":"*********************************************************************","test:coverage":"pnpm test:watch --coverage","test:coverage:ci":"pnpm test:ci --coverage","test:serve-coverage":"http-server ./coverage/lcov-report --gzip true -p 0 -o --silent","test:coverage:serve":"concurrently --prefix none --kill-others \"pnpm test:coverage\" \"pnpm test:serve-coverage\""},"devDependencies":{"@alessiofrittoli/node-scripts":"3.3.0","@alessiofrittoli/stream-writer":"^1.4.0","@eslint/js":"^9.39.2","@jest/globals":"^30.2.0","@types/inline-css":"^3.0.4","@types/jest":"^30.0.0","@types/node":"^25.0.3","concurrently":"^9.2.1","cross-env":"^10.1.0","dotenv":"^17.2.3","eslint":"^9.39.2","globals":"^16.5.0","http-server":"^14.1.1","jest":"^30.2.0","ts-jest":"^29.4.6","ts-node":"^10.9.2","tsup":"^8.5.1","typescript":"^5.9.3","typescript-eslint":"^8.50.0"},"dependencies":{"@alessiofrittoli/crypto-buffer":"^3.9.0","@alessiofrittoli/stream-reader":"^2.6.1","@alessiofrittoli/url-utils":"^3.7.1","bufferutil":"^4.1.0","inline-css":"^4.0.3","puppeteer":"^24.34.0"},"gitHead":"56654468963cd42f44f934c4738f7328b6efb089","_id":"@alessiofrittoli/html-to-pdf@1.1.0","_nodeVersion":"22.15.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-re0RCs6V8s8cGP4YCTfpIMCIHGO061ZUOa4HRHtxumZMQWpObKlpj0go+UmuYEWexHPyKywczrmW5GCiHtvhkQ==","shasum":"900fdbde87a4a0d77954d0d5233df030832a3764","tarball":"https://registry.npmjs.org/@alessiofrittoli/html-to-pdf/-/html-to-pdf-1.1.0.tgz","fileCount":7,"unpackedSize":27448,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIE14FtQiijm25fBdkXYVX5C4acHnfmIKLkdMcDVREzgAAiBaHyqAOej/yqwRLkwhGCOuooMHFafCM0sCXFwDvXL++g=="}]},"_npmUser":{"name":"alessiofrittoli","email":"info@alessiofrittoli.it"},"directories":{},"maintainers":[{"name":"alessiofrittoli","email":"info@alessiofrittoli.it"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/html-to-pdf_1.1.0_1766352493373_0.3184646958697641"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-21T18:51:20.872Z","modified":"2025-12-21T21:28:13.739Z","1.0.0-alpha.1":"2025-12-21T18:51:21.148Z","1.0.0":"2025-12-21T18:56:31.565Z","1.1.0":"2025-12-21T21:28:13.514Z"},"bugs":{"url":"https://github.com/alessiofrittoli/html-to-pdf/issues","email":"info@alessiofrittoli.it"},"author":{"name":"Alessio Frittoli","email":"info@alessiofrittoli.it","url":"https://alessiofrittoli.it"},"license":"MIT","homepage":"https://github.com/alessiofrittoli/html-to-pdf#readme","keywords":["nodejs","npm","pdf"],"repository":{"type":"git","url":"git+https://github.com/alessiofrittoli/html-to-pdf.git"},"description":"Easily convert HTML to PDF","maintainers":[{"name":"alessiofrittoli","email":"info@alessiofrittoli.it"}],"readme":"# Html to PDF 📓\n\n[![NPM Latest Version][version-badge]][npm-url] [![Coverage Status][coverage-badge]][coverage-url] [![Socket Status][socket-badge]][socket-url] [![NPM Monthly Downloads][downloads-badge]][npm-url] [![Dependencies][deps-badge]][deps-url]\n\n[![GitHub Sponsor][sponsor-badge]][sponsor-url]\n\n[version-badge]: https://img.shields.io/npm/v/%40alessiofrittoli%2Fhtml-to-pdf\n[npm-url]: https://npmjs.org/package/%40alessiofrittoli%2Fhtml-to-pdf\n[coverage-badge]: https://coveralls.io/repos/github/alessiofrittoli/html-to-pdf/badge.svg\n[coverage-url]: https://coveralls.io/github/alessiofrittoli/html-to-pdf\n[socket-badge]: https://socket.dev/api/badge/npm/package/@alessiofrittoli/html-to-pdf\n[socket-url]: https://socket.dev/npm/package/@alessiofrittoli/html-to-pdf/overview\n[downloads-badge]: https://img.shields.io/npm/dm/%40alessiofrittoli%2Fhtml-to-pdf.svg\n[deps-badge]: https://img.shields.io/librariesio/release/npm/%40alessiofrittoli%2Fhtml-to-pdf\n[deps-url]: https://libraries.io/npm/%40alessiofrittoli%2Fhtml-to-pdf\n[sponsor-badge]: https://img.shields.io/static/v1?label=Fund%20this%20package&message=%E2%9D%A4&logo=GitHub&color=%23DB61A2\n[sponsor-url]: https://github.com/sponsors/alessiofrittoli\n\n## Easily convert HTML to PDF\n\n### Table of Contents\n\n- [Getting started](#getting-started)\n- [API Reference](#api-reference)\n- [Examples](#examples)\n  - [Basic usage](#basic-usage)\n  - [Generate a PDF from a webpage](#generate-a-pdf-from-a-webpage)\n  - [Store generated PDF into a file](#store-generated-pdf-into-a-file)\n  - [Disabling inline CSS](#disabling-inline-css)\n  - [Loading custom fonts](#loading-custom-fonts)\n    - [Load custom font from remote URL](#load-custom-font-from-remote-url)\n    - [Load custom font declaration from local file](#load-custom-font-declaration-from-local-file)\n    - [Load custom font from local file](#load-custom-font-from-local-file)\n  - [Generating multiple pdf with the same constructed instance](#generating-multiple-pdf-with-the-same-constructed-instance)\n  - [Rendering Readable Streams](#rendering-readable-streams)\n- [Development](#development)\n  - [Install depenendencies](#install-depenendencies)\n  - [Build the source code](#build-the-source-code)\n  - [ESLint](#eslint)\n  - [Jest](#jest)\n- [Contributing](#contributing)\n- [Security](#security)\n- [Credits](#made-with-)\n\n---\n\n### Getting started\n\nRun the following command to start using `html-to-pdf` in your projects:\n\n```bash\nnpm i @alessiofrittoli/html-to-pdf\n```\n\nor using `pnpm`\n\n```bash\npnpm i @alessiofrittoli/html-to-pdf\n```\n\n> [!WARNING]\n> This package uses `puppeteer` and cannot be external, thus it needs to be installed in your project by running\n>\n> ```bash\n> pnpm i puppeteer\n> ```\n\nthen import it and easily use it like this\n\n```ts\nimport { PDF } from \"@alessiofrittoli/html-to-pdf\";\n\nconst content = `\n  <html>\n    <body>\n      <h1>My first PDF!</h1>\n    </body>\n  </html>\n`;\n\nconst path = \"folder/my-first-pdf.pdf\";\n\nawait new PDF({ content, path }).generate();\n```\n\n---\n\n### API Reference\n\n#### Supported input types\n\nWe accept multiple input types to provide high flexibility by using [`coerceToUint8Array()`](https://npmjs.com/package/@alessiofrittoli/crypto-buffer#coercetouint8array) exported by [@alessiofrittoli/crypto-buffer](https://npmjs.com/package/@alessiofrittoli/crypto-buffer) which gives us a standard view of the provided data.\n\nSee [`coerceToUint8Array()`](https://npmjs.com/package/@alessiofrittoli/crypto-buffer#coercetouint8array) for a list of supported data type.\n\n---\n\n### Examples\n\n#### Basic usage\n\n```ts\nimport { PDF } from \"@alessiofrittoli/html-to-pdf\";\n\nconst content = `\n  <html>\n    <body>\n      <h1>My first PDF!</h1>\n    </body>\n  </html>\n`;\n\nconst buffer = await new PDF({ content }).generate();\n// do something with pdf `buffer`\n```\n\n---\n\n#### Generate a PDF from a webpage\n\n```ts\nimport { PDF } from \"@alessiofrittoli/html-to-pdf\";\n\nconst url = \"https://google.com\";\n\nconst buffer = await new PDF({ url }).generate();\n// do something with pdf `buffer`\n```\n\n---\n\n#### Store generated PDF into a file\n\n```ts\nimport { join } from \"path\";\nimport { PDF } from \"@alessiofrittoli/html-to-pdf\";\n\nconst content = `...`;\nconst path = \"folder/my-first-pdf.pdf\";\n\nconst buffer = await new PDF({ content, path }).generate();\n// do something else with pdf `buffer`\n```\n\n---\n\n#### Disabling inline CSS\n\nBy default all styles defined in a `<style />` HTML tag get applied to the corresponding HTML NodeElement. You can opt-out by this behavior by setting `inlineCss` to `false`.\n\nThis may be usefull to properly load custom fonts using `@font-face` declaration. If you still want to inline CSS (which is recommended) but load custom fonts, please read [Loading custom fonts](#loading-custom-fonts) section.\n\n```ts\nimport { PDF } from \"@alessiofrittoli/html-to-pdf\";\n\nconst content = `\n  <html>\n    <head>\n      <style>\n        ...\n      </style>\n    </head>\n    <body>\n      <h1>My first PDF!</h1>\n    </body>\n  </html>\n`;\n\n// parsed markup will contain `<style />` tag before rendering the PDF.\nawait new PDF({ content }).generate();\n```\n\n---\n\n#### Loading custom fonts\n\nYou can load additional styles that won't be parsed before rendering the PDF by defining URLs, paths or CSS declarations through the `GeneratePdfOptions.styles` option.\n\n##### Load custom font from remote URL\n\n```ts\nimport { PDF, type StyleTagsOptions } from \"@alessiofrittoli/html-to-pdf\";\n\nconst content = `\n  <html class='corinthia-regular'>\n    <head>\n      <style>\n        .corinthia-regular {\n          font-family: \"Corinthia\", cursive;\n          font-weight: 400;\n          font-style: normal;\n        }\n      </style>\n    </head>\n    <body>\n      <h1>My first PDF!</h1>\n    </body>\n  </html>\n`;\n\nconst styles: StyleTagsOptions = [\n  { url: \"https://fonts.googleapis.com/css2?family=Corinthia&display=swap\" },\n];\n\nconst pdf = new PDF({ content, styles });\n```\n\n---\n\n##### Load custom font declaration from local file\n\n```ts\nimport { join } from \"path\";\nimport { PDF, type StyleTagsOptions } from \"@alessiofrittoli/html-to-pdf\";\n\nconst content = `\n  <html class='corinthia-regular'>\n    <head>\n      <style>\n        .corinthia-regular {\n          font-family: \"Corinthia\", cursive;\n          font-weight: 400;\n          font-style: normal;\n        }\n      </style>\n    </head>\n    <body>\n      <h1>My first PDF!</h1>\n    </body>\n  </html>\n`;\n\nconst styles: StyleTagsOptions = [\n  { path: join(process.cwd(), \"font-css-file-declaration.css\") },\n];\n\nconst pdf = new PDF({ content, styles });\n```\n\n---\n\n```css\n/* font-css-file-declaration.css */\n/* latin */\n@font-face {\n  font-family: \"Corinthia\";\n  font-style: normal;\n  font-weight: 400;\n  font-display: swap;\n  src: url(https://fonts.gstatic.com/s/corinthia/v13/wEO_EBrAnchaJyPMHE01VvoK_kgXiQ.woff2)\n    format(\"woff2\");\n  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,\n    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,\n    U+2212, U+2215, U+FEFF, U+FFFD;\n}\n```\n\n---\n\n##### Load custom font from local file\n\nIf you need to load a custom font that will be available in off-line conditions or you don't want to depend on external resources, you can embed the font by encoding it to base64.\n\n```ts\nimport { join } from \"path\";\nimport { Base64 } from \"@alessiofrittoli/crypto-encoder\";\nimport { PDF, type StyleTagsOptions } from \"@alessiofrittoli/html-to-pdf\";\n\nconst content = `\n  <html class='corinthia-regular'>\n    <head>\n      <style>\n        .corinthia-regular {\n          font-family: \"Corinthia\", cursive;\n          font-weight: 400;\n          font-style: normal;\n        }\n      </style>\n    </head>\n    <body>\n      <h1>My first PDF!</h1>\n    </body>\n  </html>\n`;\n\nconst fontBasePath = resolve(process.cwd(), \"assets/fonts/Corinthia\");\nconst fontfile = readFileSync(join(fontBasePath, \"local-font-filename.woff2\"));\nconst fontBase64 = Base64.encode(fontfile, false);\nconst css = readFileSync(\n  join(fontBasePath, \"font-css-file-declaration.css\"),\n  \"utf-8\"\n).replace(\"url(custom-font-url)\", `url(data:font/woff2;base64,${fontBase64})`);\n\nconst styles: StyleTagsOptions = [{ content: css }];\n\nconst pdf = new PDF({ content, styles });\n```\n\n---\n\n```css\n/* font-css-file-declaration.css */\n/* latin */\n@font-face {\n  font-family: \"Corinthia\";\n  font-style: normal;\n  font-weight: 400;\n  font-display: swap;\n  src: url(custom-font-url) format(\"woff2\");\n  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,\n    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,\n    U+2212, U+2215, U+FEFF, U+FFFD;\n}\n```\n\n---\n\n#### Generating multiple pdf with the same constructed instance\n\nYou can generate multiple PDFs with a single constructed instance of `PDF` which shares common options and eventually override or add new options for each generated pdf.\n\nThis is possible since customization options can be either passed to the `PDF` constructor or to the `PDF.generate()` method.\n\n> [!WARNING]\n> Note that you cannot generate multiple PDFs with the same ReadableStream since it can be read once.\n> If you still need to do so, please set the `content` once by passing the `ReadableStream` in the constructor.\n> Please refer to the [Rendering Readable Streams](#rendering-readable-streams) section for more info.\n\n```ts\nimport { PDF } from \"@alessiofrittoli/html-to-pdf\";\n\nconst pdf = new PDF({\n  format: \"A4\",\n  styles: [{ path: \"/absolute/path/to/custom/style.css\" }],\n});\n\nawait pdf.generate({ content: \"PDF 1\", path: \"folder/pdf-1.pdf\" });\nawait pdf.generate({\n  content: \"PDF 2\",\n  path: \"folder/pdf-2.pdf\",\n  format: \"A3\",\n  landscape: true,\n});\n```\n\n---\n\n#### Rendering Readable Streams\n\nIn addition to the various [supported input types](#supported-input-types), this library also supports `ReadableStreams` (it happens more often than you think).\n\nIn this example we render async React Server Components inside a PDF page.\n\nAsynchronous React Server Components needs to be rendered using [`renderToReadableStream()`](https://react.dev/reference/react-dom/server/renderToReadableStream) which returns a Promise that resolves a `ReadableStream` so this is a perfect example on how to deal with it.\n\n```tsx\nimport { PDF } from \"@alessiofrittoli/html-to-pdf\";\n\nconst MyAsyncPdfComponent: React.FC = async () => {\n  await { ...someAsyncTask };\n\n  return (\n    <html>\n      <body>\n        <h1>My React PDF Component</h1>\n      </body>\n    </html>\n  );\n};\n\nconst { renderToReadableStream } = await import(\"react-dom/server\");\n\nconst content = await renderToReadableStream(<MyAsyncPdfComponent />);\nconst pdf = new PDF({ content });\n\nawait pdf.generate();\n```\n\n---\n\n### Development\n\n#### Install depenendencies\n\n```bash\nnpm install\n```\n\nor using `pnpm`\n\n```bash\npnpm i\n```\n\n#### Build the source code\n\nRun the following command to test and build code for distribution.\n\n```bash\npnpm build\n```\n\n#### [ESLint](https://www.npmjs.com/package/eslint)\n\nwarnings / errors check.\n\n```bash\npnpm lint\n```\n\n#### [Jest](https://npmjs.com/package/jest)\n\nRun all the defined test suites by running the following:\n\n```bash\n# Run tests and watch file changes.\npnpm test:watch\n\n# Run tests in a CI environment.\npnpm test:ci\n```\n\n- See [`package.json`](./package.json) file scripts for more info.\n\nRun tests with coverage.\n\nAn HTTP server is then started to serve coverage files from `./coverage` folder.\n\n⚠️ You may see a blank page the first time you run this command. Simply refresh the browser to see the updates.\n\n```bash\ntest:coverage:serve\n```\n\n---\n\n### Contributing\n\nContributions are truly welcome!\n\nPlease refer to the [Contributing Doc](./CONTRIBUTING.md) for more information on how to start contributing to this project.\n\nHelp keep this project up to date with [GitHub Sponsor][sponsor-url].\n\n[![GitHub Sponsor][sponsor-badge]][sponsor-url]\n\n---\n\n### Security\n\nIf you believe you have found a security vulnerability, we encourage you to **_responsibly disclose this and NOT open a public issue_**. We will investigate all legitimate reports. Email `security@alessiofrittoli.it` to disclose any security vulnerabilities.\n\n### Made with ☕\n\n<table style='display:flex;gap:20px;'>\n  <tbody>\n    <tr>\n      <td>\n        <img alt=\"avatar\" src='https://avatars.githubusercontent.com/u/35973186' style='width:60px;border-radius:50%;object-fit:contain;'>\n      </td>\n      <td>\n        <table style='display:flex;gap:2px;flex-direction:column;'>\n          <tbody>\n              <tr>\n                <td>\n                  <a href='https://github.com/alessiofrittoli' target='_blank' rel='noopener'>Alessio Frittoli</a>\n                </td>\n              </tr>\n              <tr>\n                <td>\n                  <small>\n                    <a href='https://alessiofrittoli.it' target='_blank' rel='noopener'>https://alessiofrittoli.it</a> |\n                    <a href='mailto:info@alessiofrittoli.it' target='_blank' rel='noopener'>info@alessiofrittoli.it</a>\n                  </small>\n                </td>\n              </tr>\n          </tbody>\n        </table>\n      </td>\n    </tr>\n  </tbody>\n</table>\n","readmeFilename":"README.md"}