{"id":13588842,"url":"https://github.com/westy92/html-pdf-chrome","last_synced_at":"2025-05-14T08:07:32.269Z","repository":{"id":20675728,"uuid":"90583576","full_name":"westy92/html-pdf-chrome","owner":"westy92","description":"HTML to PDF or image (jpeg, png, webp) converter via Chrome/Chromium","archived":false,"fork":false,"pushed_at":"2025-05-09T22:44:01.000Z","size":1365,"stargazers_count":785,"open_issues_count":19,"forks_count":61,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-05-09T23:28:24.516Z","etag":null,"topics":["chrome","chromium","google","google-chrome","headless","headless-browsers","headless-chrome","headless-chromium","html","html-pdf-chrome","javascript","linux","macos","node-js","nodejs","pdf","pdf-generation","pdf-generator","typescript","windows"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/html-pdf-chrome","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/westy92.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["westy92"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2017-05-08T03:40:02.000Z","updated_at":"2025-04-24T01:25:59.000Z","dependencies_parsed_at":"2023-10-16T03:00:33.436Z","dependency_job_id":"d1a269be-1fd1-4f09-8619-5459cb1c7617","html_url":"https://github.com/westy92/html-pdf-chrome","commit_stats":{"total_commits":510,"total_committers":12,"mean_commits":42.5,"dds":0.5686274509803921,"last_synced_commit":"21a979696048995cfed589970e73795a1be10ae3"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/westy92%2Fhtml-pdf-chrome","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/westy92%2Fhtml-pdf-chrome/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/westy92%2Fhtml-pdf-chrome/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/westy92%2Fhtml-pdf-chrome/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/westy92","download_url":"https://codeload.github.com/westy92/html-pdf-chrome/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253341570,"owners_count":21893546,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chrome","chromium","google","google-chrome","headless","headless-browsers","headless-chrome","headless-chromium","html","html-pdf-chrome","javascript","linux","macos","node-js","nodejs","pdf","pdf-generation","pdf-generator","typescript","windows"],"created_at":"2024-08-01T15:06:58.480Z","updated_at":"2025-05-14T08:07:32.237Z","avatar_url":"https://github.com/westy92.png","language":"TypeScript","funding_links":["https://github.com/sponsors/westy92"],"categories":["TypeScript","JAVASCRIPT","chrome","windows"],"sub_categories":[],"readme":"# html-pdf-chrome\n\n[![npm version](https://badge.fury.io/js/html-pdf-chrome.svg)](https://www.npmjs.com/package/html-pdf-chrome)\n[![Build Status](https://github.com/westy92/html-pdf-chrome/actions/workflows/github-actions.yml/badge.svg)](https://github.com/westy92/html-pdf-chrome/actions/workflows/github-actions.yml?query=branch%3Amaster)\n[![Maintainability](https://api.codeclimate.com/v1/badges/9395ded652937f958a41/maintainability)](https://codeclimate.com/github/westy92/html-pdf-chrome/maintainability)\n[![Code Coverage](https://codecov.io/gh/westy92/html-pdf-chrome/branch/master/graph/badge.svg)](https://codecov.io/gh/westy92/html-pdf-chrome)\n[![Known Vulnerabilities](https://snyk.io/test/github/westy92/html-pdf-chrome/badge.svg)](https://snyk.io/test/github/westy92/html-pdf-chrome)\n[![Funding Status](https://img.shields.io/github/sponsors/westy92)](https://github.com/sponsors/westy92)\n\nHTML to PDF or image (jpeg, png, webp) converter via Chrome/Chromium.\n\n## Prerequisites\n\n* Latest Chrome/Chromium\n* Windows, macOS, or Linux\n* A [currently supported version of Node.js](https://nodejs.org/en/about/releases/)\n\n## Installation\n\n```bash\nnpm install --save html-pdf-chrome\n```\n\n## Security\n\nThis library is **_NOT_** meant to accept untrusted user input. Doing so may have serious security risks such as Server-Side Request Forgery (SSRF).\n\n### CORS\n\nIf you run into CORS issues, try using the `--disable-web-security` Chrome flag, either when you start Chrome externally, or in `options.chromeFlags`. This option should only be used if you fully trust the code you are executing during a print job!\n\n## Usage\n\n__Note:__ It is _strongly_ recommended that you keep Chrome running side-by-side with Node.js.  There is significant overhead starting up Chrome for each PDF generation which can be easily avoided.\n\nIt's suggested to use [pm2](http://pm2.keymetrics.io/) to ensure Chrome continues to run.  If it crashes, it will restart automatically.\n\nAs of this writing, headless Chrome uses about 65mb of RAM while idle.\n\n```bash\n# install pm2 globally\nnpm install -g pm2\n# start Chrome and be sure to specify a port to use in the html-pdf-chrome options.\npm2 start google-chrome \\\n  --interpreter none \\\n  -- \\\n  --headless \\\n  --disable-gpu \\\n  --disable-translate \\\n  --disable-extensions \\\n  --disable-background-networking \\\n  --safebrowsing-disable-auto-update \\\n  --disable-sync \\\n  --metrics-recording-only \\\n  --disable-default-apps \\\n  --no-first-run \\\n  --mute-audio \\\n  --hide-scrollbars \\\n  --remote-debugging-port=\u003cport goes here\u003e\n# run your Node.js app.\n```\n\nTypeScript:\n\n```js\nimport * as htmlPdf from 'html-pdf-chrome';\n\nconst html = '\u003cp\u003eHello, world!\u003c/p\u003e';\nconst options: htmlPdf.CreateOptions = {\n  port: 9222, // port Chrome is listening on\n};\n\n// async\nconst pdf = await htmlPdf.create(html, options);\nawait pdf.toFile('test.pdf');\nconst base64 = pdf.toBase64();\nconst buffer = pdf.toBuffer();\nconst stream = pdf.toStream();\n\n// Promise\nhtmlPdf.create(html, options).then((pdf) =\u003e pdf.toFile('test.pdf'));\nhtmlPdf.create(html, options).then((pdf) =\u003e pdf.toBase64());\nhtmlPdf.create(html, options).then((pdf) =\u003e pdf.toBuffer());\nhtmlPdf.create(html, options).then((pdf) =\u003e pdf.toStream());\n```\n\nJavaScript:\n\n```js\nconst htmlPdf = require('html-pdf-chrome');\n\nconst html = '\u003cp\u003eHello, world!\u003c/p\u003e';\nconst options = {\n  port: 9222, // port Chrome is listening on\n};\n\nhtmlPdf.create(html, options).then((pdf) =\u003e pdf.toFile('test.pdf'));\nhtmlPdf.create(html, options).then((pdf) =\u003e pdf.toBase64());\nhtmlPdf.create(html, options).then((pdf) =\u003e pdf.toBuffer());\nhtmlPdf.create(html, options).then((pdf) =\u003e pdf.toStream());\n```\n\nView the full documentation in the source code.\n\n### Saving as a Screenshot\n\nBy default, pages are saved as a PDF. To save as a screenshot instead, supply `screenshotOptions`.\nAll supported options can be viewed [here](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-captureScreenshot).\n\n```js\nconst htmlPdf = require('html-pdf-chrome');\n\nconst html = '\u003cp\u003eHello, world!\u003c/p\u003e';\nconst options = {\n  port: 9222, // port Chrome is listening on\n  screenshotOptions: {\n    format: 'png', // png, jpeg, or webp. Optional, defaults to png.\n    // quality: 100, // Optional, quality percent (jpeg only)\n\n    // optional, defaults to entire window\n    clip: {\n      x: 0,\n      y: 0,\n      width: 100,\n      height: 200,\n      scale: 1,\n    },\n  },\n  // Optional. Options here: https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setDeviceMetricsOverride\n  deviceMetrics: {\n    width: 1000,\n    height: 1000,\n    deviceScaleFactor: 0,\n    mobile: false,\n  },\n};\n\nhtmlPdf.create(html, options).then((pdf) =\u003e pdf.toFile('test.png'));\n```\n\n### Using an External Site\n\n```js\nimport * as htmlPdf from 'html-pdf-chrome';\n\nconst options: htmlPdf.CreateOptions = {\n  port: 9222, // port Chrome is listening on\n};\n\nconst url = 'https://github.com/westy92/html-pdf-chrome';\nconst pdf = await htmlPdf.create(url, options);\n```\n\n### Using Markdown\n\n```js\nimport * as htmlPdf from 'html-pdf-chrome';\nimport * as marked from 'marked';\n\nconst options: htmlPdf.CreateOptions = {\n  port: 9222, // port Chrome is listening on\n};\n\nconst html = marked('# Hello [World](https://www.google.com/)!');\nconst pdf = await htmlPdf.create(html, options);\n```\n\n### Using a Template Engine\n\nPug (formerly known as Jade)\n\n```js\nimport * as htmlPdf from 'html-pdf-chrome';\nimport * as pug from 'pug';\n\nconst template = pug.compile('p Hello, #{noun}!');\nconst templateData = {\n  noun: 'world',\n};\nconst options: htmlPdf.CreateOptions = {\n  port: 9222, // port Chrome is listening on\n};\n\nconst html = template(templateData);\nconst pdf = await htmlPdf.create(html, options);\n```\n\n### HTTP Headers\n\nSpecify additional headers you wish to send with your request via `CreateOptions.extraHTTPHeaders`.\n\n```js\nconst options: HtmlPdf.CreateOptions = {\n  port: 9222, // port Chrome is listening on\n  extraHTTPHeaders: {\n    'Authorization': 'Bearer 123',\n    'X-Custom-Test-Header': 'This is great!',\n  },\n};\n\nconst pdf = await HtmlPdf.create('https://httpbin.org/headers', options);\n```\n\n### Custom Headers and Footers\n\n_Note: Requires Chrome 65 or later._\n\nYou can optionally provide an HTML template for a custom header and/or footer.\n\nA few classes can be used to inject printing values:\n\n* `date` - formatted print date\n* `title` - document title\n* `url` - document location\n* `pageNumber` - current page number\n* `totalPages` - total pages in the document\n\nYou can tweak the margins with the `printOptions` of `marginTop`, `marginBottom`, `marginLeft`, and `marginRight`.\n\nAt this time, you must inline any images using [base64 encoding](http://www.bigfastblog.com/embed-base64-encoded-images-inline-in-html).\n\nYou can view how Chrome lays out the templates [here](https://cs.chromium.org/chromium/src/components/printing/resources/print_preview_page.html).\n\n#### Example\n\n```js\nconst pdf = await htmlPdf.create(html, {\n  port,\n  printOptions: {\n    displayHeaderFooter: true,\n    headerTemplate: `\n      \u003cdiv class=\"text center\"\u003e\n        Page \u003cspan class=\"pageNumber\"\u003e\u003c/span\u003e of \u003cspan class=\"totalPages\"\u003e\u003c/span\u003e\n      \u003c/div\u003e\n    `,\n    footerTemplate: '\u003cdiv class=\"text center\"\u003eCustom footer!\u003c/div\u003e',\n  },\n});\n```\n\n### Trigger Render Completion\n\nThere are a few `CompletionTrigger` types that wait for something to occur before triggering PDF printing.\n\n* Callback - waits for a callback to be called\n* Element - waits for an element to be injected into the DOM\n* Event - waits for an Event to fire\n* Timer - waits a specified amount of time\n* LifecycleEvent - waits for a Chrome page lifecycle event\n* Variable - waits for a variable to be set to `true`\n* Custom - extend `htmlPdf.CompletionTrigger.CompletionTrigger`\n\n```js\nconst options: htmlPdf.CreateOptions = {\n  port: 9222, // port Chrome is listening on\n  completionTrigger: new htmlPdf.CompletionTrigger.Timer(5000), // milliseconds\n};\n\n// Alternative completionTrigger options:\nnew htmlPdf.CompletionTrigger.Callback(\n  'cbName', // optional, name of the callback to define for the browser to call when finished rendering.  Defaults to 'htmlPdfCb'.\n  5000 // optional, timeout (milliseconds)\n),\n\nnew htmlPdf.CompletionTrigger.Element(\n  'div#myElement', // name of the DOM element to wait for\n  5000 // optional, timeout (milliseconds)\n),\n\nnew htmlPdf.CompletionTrigger.Event(\n  'myEvent', // name of the event to listen for\n  '#myElement', // optional DOM element CSS selector to listen on, defaults to body\n  5000 // optional timeout (milliseconds)\n),\n\nnew htmlPdf.CompletionTrigger.LifecycleEvent(\n  'networkIdle', // name of the Chrome lifecycle event to listen for. Defaults to 'firstMeaningfulPaint'.\n  5000 // optional timeout (milliseconds)\n),\n\nnew htmlPdf.CompletionTrigger.Variable(\n  'myVarName', // optional, name of the variable to wait for.  Defaults to 'htmlPdfDone'\n  5000 // optional, timeout (milliseconds)\n),\n```\n\n## License\n\nhtml-pdf-chrome is released under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwesty92%2Fhtml-pdf-chrome","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwesty92%2Fhtml-pdf-chrome","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwesty92%2Fhtml-pdf-chrome/lists"}