├── .github └── workflows │ └── main.yml ├── .gitignore ├── README.md ├── package.json ├── src ├── __fixtures__ │ └── basic.ts ├── __mocks__ │ └── puppeteer │ │ └── index.ts ├── __tests__ │ └── HTMLToPDF.spec.ts ├── index.ts ├── models │ └── HTMLToPDF.ts └── types.ts ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: [ master ] 5 | pull_request: 6 | branches: [ master ] 7 | jobs: 8 | ci: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v2 13 | with: 14 | node-version: '14' 15 | - name: Dependencies 16 | run: yarn 17 | - name: Test 18 | run: yarn test 19 | - name: Build 20 | run: yarn build 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | build/ 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | 12 | # Diagnostic reports (https://nodejs.org/api/report.html) 13 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 14 | 15 | # Runtime data 16 | pids 17 | *.pid 18 | *.seed 19 | *.pid.lock 20 | 21 | # Directory for instrumented libs generated by jscoverage/JSCover 22 | lib-cov 23 | 24 | # Coverage directory used by tools like istanbul 25 | coverage 26 | *.lcov 27 | 28 | # nyc test coverage 29 | .nyc_output 30 | 31 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 32 | .grunt 33 | 34 | # Bower dependency directory (https://bower.io/) 35 | bower_components 36 | 37 | # node-waf configuration 38 | .lock-wscript 39 | 40 | # Compiled binary addons (https://nodejs.org/api/addons.html) 41 | build/Release 42 | 43 | # Dependency directories 44 | node_modules/ 45 | jspm_packages/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Optional REPL history 57 | .node_repl_history 58 | 59 | # Output of 'npm pack' 60 | *.tgz 61 | 62 | # Yarn Integrity file 63 | .yarn-integrity 64 | 65 | # dotenv environment variables file 66 | .env 67 | .env.test 68 | 69 | # parcel-bundler cache (https://parceljs.org/) 70 | .cache 71 | 72 | # next.js build output 73 | .next 74 | 75 | # nuxt.js build output 76 | .nuxt 77 | 78 | # vuepress build output 79 | .vuepress/dist 80 | 81 | # Serverless directories 82 | .serverless/ 83 | 84 | # FuseBox cache 85 | .fusebox/ 86 | 87 | # DynamoDB Local files 88 | .dynamodb/ 89 | 90 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 91 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 92 | 93 | # User-specific stuff 94 | .idea/**/workspace.xml 95 | .idea/**/tasks.xml 96 | .idea/**/usage.statistics.xml 97 | .idea/**/dictionaries 98 | .idea/**/shelf 99 | 100 | # Generated files 101 | .idea/**/contentModel.xml 102 | 103 | # Sensitive or high-churn files 104 | .idea/**/dataSources/ 105 | .idea/**/dataSources.ids 106 | .idea/**/dataSources.local.xml 107 | .idea/**/sqlDataSources.xml 108 | .idea/**/dynamic.xml 109 | .idea/**/uiDesigner.xml 110 | .idea/**/dbnavigator.xml 111 | 112 | # Gradle 113 | .idea/**/gradle.xml 114 | .idea/**/libraries 115 | 116 | # Gradle and Maven with auto-import 117 | # When using Gradle or Maven with auto-import, you should exclude module files, 118 | # since they will be recreated, and may cause churn. Uncomment if using 119 | # auto-import. 120 | # .idea/modules.xml 121 | # .idea/*.iml 122 | # .idea/modules 123 | # *.iml 124 | # *.ipr 125 | 126 | # CMake 127 | cmake-build-*/ 128 | 129 | # Mongo Explorer plugin 130 | .idea/**/mongoSettings.xml 131 | 132 | # File-based project format 133 | *.iws 134 | 135 | # IntelliJ 136 | out/ 137 | 138 | # mpeltonen/sbt-idea plugin 139 | .idea_modules/ 140 | 141 | # JIRA plugin 142 | atlassian-ide-plugin.xml 143 | 144 | # Cursive Clojure plugin 145 | .idea/replstate.xml 146 | 147 | # Crashlytics plugin (for Android Studio and IntelliJ) 148 | com_crashlytics_export_strings.xml 149 | crashlytics.properties 150 | crashlytics-build.properties 151 | fabric.properties 152 | 153 | # Editor-based Rest Client 154 | .idea/httpRequests 155 | 156 | # Android studio 3.1+ serialized cache file 157 | .idea/caches/build_file_checksums.ser 158 | 159 | # Cache files for Sublime Text 160 | *.tmlanguage.cache 161 | *.tmPreferences.cache 162 | *.stTheme.cache 163 | 164 | # Workspace files are user-specific 165 | *.sublime-workspace 166 | 167 | # Project files should be checked into the repository, unless a significant 168 | # proportion of contributors will probably not be using Sublime Text 169 | # *.sublime-project 170 | 171 | # SFTP configuration file 172 | sftp-config.json 173 | 174 | # Package control specific files 175 | Package Control.last-run 176 | Package Control.ca-list 177 | Package Control.ca-bundle 178 | Package Control.system-ca-bundle 179 | Package Control.cache/ 180 | Package Control.ca-certs/ 181 | Package Control.merged-ca-bundle 182 | Package Control.user-ca-bundle 183 | oscrypto-ca-bundle.crt 184 | bh_unicode_properties.cache 185 | 186 | # Sublime-github package stores a github token in this file 187 | # https://packagecontrol.io/packages/sublime-github 188 | GitHub.sublime-settings 189 | 190 | # General 191 | .DS_Store 192 | .AppleDouble 193 | .LSOverride 194 | 195 | # Icon must end with two \r 196 | Icon 197 | 198 | # Thumbnails 199 | ._* 200 | 201 | # Files that might appear in the root of a volume 202 | .DocumentRevisions-V100 203 | .fseventsd 204 | .Spotlight-V100 205 | .TemporaryItems 206 | .Trashes 207 | .VolumeIcon.icns 208 | .com.apple.timemachine.donotpresent 209 | 210 | # Directories potentially created on remote AFP share 211 | .AppleDB 212 | .AppleDesktop 213 | Network Trash Folder 214 | Temporary Items 215 | .apdisk 216 | 217 | # Windows thumbnail cache files 218 | Thumbs.db 219 | Thumbs.db:encryptable 220 | ehthumbs.db 221 | ehthumbs_vista.db 222 | 223 | # Dump file 224 | *.stackdump 225 | 226 | # Folder config file 227 | [Dd]esktop.ini 228 | 229 | # Recycle Bin used on file shares 230 | $RECYCLE.BIN/ 231 | 232 | # Windows Installer files 233 | *.cab 234 | *.msi 235 | *.msix 236 | *.msm 237 | *.msp 238 | 239 | # Windows shortcuts 240 | *.lnk 241 | 242 | .vscode/* 243 | !.vscode/settings.json 244 | !.vscode/tasks.json 245 | !.vscode/launch.json 246 | !.vscode/extensions.json 247 | 248 | *.tmproj 249 | *.tmproject 250 | tmtags 251 | 252 | *~ 253 | 254 | # temporary files which can be created if a process still has a handle open of a deleted file 255 | .fuse_hidden* 256 | 257 | # KDE directory preferences 258 | .directory 259 | 260 | # Linux trash folder which might appear on any partition or disk 261 | .Trash-* 262 | 263 | # .nfs files are created when an open file is removed but is still being accessed 264 | .nfs* 265 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # html-to-pdf 2 | 3 | A library for converting HTML with CSS to PDF. 4 | 5 | 6 | ### Dependencies 7 | 8 | This library uses Puppeteer to generate PDF's. 9 | 10 | Some systems may work out of the box, others may not. To allow Puppeteer to spin up correctly, you may need to install some additional system dependencies. 11 | 12 | For pointers on how to make puppeteer work in your environment, see https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-in-docker 13 | 14 | ### Basic usage 15 | 16 | This library exports a method allowing conversion of HTML to PDF. When invoked with a valid HTML template as the first argument, a Buffer is returned containing a PDF document, along with the `application/pdf` mime type. The second argument is a configuration object, allowing customisation of Puppeteer, or the output of the PDF. 17 | 18 | ```javascript 19 | const HTMLToPDF = require('convert-html-to-pdf').default; 20 | 21 | const htmlToPDF = new HTMLToPDF(` 22 |
Hello world
23 | `); 24 | 25 | htmlToPDF.convert() 26 | .then((buffer) => { 27 | // do something with the PDF file buffer 28 | }) 29 | .catch((err) => { 30 | // do something on error 31 | }); 32 | ``` 33 | 34 | Or, if using async await: 35 | 36 | ```javascript 37 | const HTMLToPDF = require('convert-html-to-pdf').default; 38 | 39 | const getPDF = async () => { 40 | const htmlToPDF = new HTMLToPDF(` 41 |
Hello world
42 | `); 43 | 44 | try { 45 | const pdf = await htmlToPDF.convert(); 46 | // do something with the PDF file buffer 47 | } catch (err) { 48 | // do something on error 49 | } 50 | }; 51 | ``` 52 | 53 | For PDF's that should contain imagery or web fonts, it's recommended to base 64 encode any assets and embed within the markup using a data URI. This will yield faster results. If you'd rather request assets over HTTP, you can do this by enabling the `waitForNetworkIdle` configuration option. 54 | 55 | ##### Example of an asset encoded as base 64 56 | ```javascript 57 | const HTMLToPDF = require('convert-html-to-pdf').default; 58 | 59 | const htmlToPDF = new HTMLToPDF(` 60 | 61 | `); 62 | 63 | htmlToPDF.convert() 64 | .then((buffer) => { 65 | // do something with the PDF file buffer 66 | }) 67 | .catch((err) => { 68 | // do something on error 69 | }); 70 | ``` 71 | 72 | ##### Example of an asset loaded over HTTP 73 | ```javascript 74 | const HTMLToPDF = require('convert-html-to-pdf').default; 75 | 76 | const htmlToPDF = new HTMLToPDF(` 77 | 78 | `, { 79 | waitForNetworkIdle: true, 80 | }); 81 | 82 | htmlToPDF.convert() 83 | .then((buffer) => { 84 | // do something with the PDF file buffer 85 | }) 86 | .catch((err) => { 87 | // do something on error 88 | }); 89 | ``` 90 | 91 | ### Configuration 92 | 93 | | property | type | description | 94 | |--------------------|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 95 | | browserOptions | LaunchOptions | The Puppeteer launch option configuration. See https://pptr.dev/#?product=Puppeteer&version=v1.19.0&show=api-puppeteerlaunchoptions for a full list. | 96 | | pdfOptions | PDFOptions | The Puppeteer PDF option configuration. See https://pptr.dev/#?product=Puppeteer&version=v1.19.0&show=api-pagepdfoptions for a full list. | 97 | | waitForNetworkIdle | boolean | By default, we assume the PDF document supplied will not contain requests over HTTP (for fastest possible PDF generation). Typically you can embed resources by base64 encoding as data URI's. If you have HTML that pulls assets or other resources over HTTP, set this to `true`. | 98 | 99 | ### Example Dockerfile 100 | 101 | If you're using this in a production Debian environment (e.g. Docker), here's an extract from a Dockerfile with the necessary dependencies needed to get up and running. 102 | 103 | ```Dockerfile 104 | FROM node:10.15.3-slim 105 | 106 | RUN apt-get update \ 107 | && apt-get install -y --no-install-recommends gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 \ 108 | libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 \ 109 | libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxi6 libxrandr2 libxrender1 \ 110 | libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget libxft-dev libfreetype6 \ 111 | && rm -rf /var/lib/apt/lists/* 112 | ``` 113 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "convert-html-to-pdf", 3 | "description": "Convert HTML to PDF in node.js", 4 | "version": "1.0.1", 5 | "main": "./lib/index.js", 6 | "types": "./lib/index.d.ts", 7 | "license": "MIT", 8 | "authors": [ 9 | "Alex Tiley " 10 | ], 11 | "keywords": [ 12 | "convert", 13 | "pdf", 14 | "html", 15 | "pdf-generator", 16 | "pdf-conversion", 17 | "pdf-creator", 18 | "pdf-builder", 19 | "puppeteer", 20 | "wkhtmltopdf", 21 | "html2pdf", 22 | "html-to-pdf", 23 | "convert-html-to-pdf", 24 | "pdf-from-html", 25 | "node", 26 | "nodejs", 27 | "javascript", 28 | "typescript", 29 | "ts", 30 | "js" 31 | ], 32 | "homepage": "https://github.com/alextiley/convert-html-to-pdf", 33 | "repository": "https://github.com/alextiley/convert-html-to-pdf", 34 | "bugs": "https://github.com/alextiley/convert-html-to-pdf/issues", 35 | "scripts": { 36 | "build": "rimraf ./lib; tsc -p tsconfig.build.json", 37 | "prepublishOnly": "yarn build", 38 | "start": "tsnd --respawn --transpile-only examples/index.ts", 39 | "test": "jest" 40 | }, 41 | "files": [ 42 | "/lib" 43 | ], 44 | "devDependencies": { 45 | "@types/jest": "^24.0.15", 46 | "@types/lodash": "^4.14.136", 47 | "@types/node": "^12.6.8", 48 | "@types/puppeteer": "^1.19.0", 49 | "jest": "^24.8.0", 50 | "rimraf": "^2.6.3", 51 | "ts-jest": "^24.0.2", 52 | "ts-node-dev": "^1.0.0-pre.40", 53 | "typescript": "^3.5.3" 54 | }, 55 | "dependencies": { 56 | "lodash": "^4.17.15", 57 | "puppeteer": "^1.19.0" 58 | }, 59 | "jest": { 60 | "clearMocks": true, 61 | "resetModules": true, 62 | "restoreMocks": true, 63 | "roots": [ 64 | "/src" 65 | ], 66 | "transform": { 67 | "^.+\\.ts?$": "ts-jest" 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/__fixtures__/basic.ts: -------------------------------------------------------------------------------- 1 | export default ` 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Hello world

9 | 10 | 11 | `; 12 | -------------------------------------------------------------------------------- /src/__mocks__/puppeteer/index.ts: -------------------------------------------------------------------------------- 1 | import noop from 'lodash/fp/noop'; 2 | 3 | export const page = { 4 | on: jest.fn().mockImplementation(noop), 5 | goto: jest.fn().mockImplementation(noop), 6 | setContent: jest.fn().mockReturnValue(Promise.resolve()), 7 | pdf: jest.fn().mockReturnValue(Promise.resolve(Buffer.from('PDF'))), 8 | }; 9 | 10 | export const browser = { 11 | newPage: jest.fn().mockReturnValue(Promise.resolve(page)), 12 | close: jest.fn(), 13 | }; 14 | 15 | export const puppeteer = { 16 | launch: jest.fn().mockReturnValue(Promise.resolve(browser)), 17 | }; 18 | 19 | export default puppeteer; 20 | -------------------------------------------------------------------------------- /src/__tests__/HTMLToPDF.spec.ts: -------------------------------------------------------------------------------- 1 | import { puppeteer } from '../__mocks__/puppeteer'; 2 | import basicMarkup from '../__fixtures__/basic'; 3 | import HTMLToPDF from '../'; 4 | 5 | describe('unit tests', () => { 6 | describe('convert', () => { 7 | it('should disable font render hinting by default, to ensure fonts render reliably across all platforms', async () => { 8 | const htmlToPDF = new HTMLToPDF(basicMarkup); 9 | await htmlToPDF.convert(); 10 | 11 | expect(puppeteer.launch).toHaveBeenCalledWith(expect.objectContaining({ 12 | args: ['--font-render-hinting=none'], 13 | })); 14 | }); 15 | 16 | it('should allow font render hinting to be enabled via browser configuration', async () => { 17 | const htmlToPDF = new HTMLToPDF(basicMarkup, { 18 | browserOptions: { 19 | args: [], 20 | }, 21 | }); 22 | await htmlToPDF.convert(); 23 | 24 | expect(puppeteer.launch).toHaveBeenCalledWith(expect.objectContaining({ 25 | args: [], 26 | })); 27 | }); 28 | 29 | it('should support custom browser settings, via configuration', async () => { 30 | const htmlToPDF = new HTMLToPDF(basicMarkup, { 31 | browserOptions: { 32 | timeout: 5000, 33 | }, 34 | }); 35 | await htmlToPDF.convert(); 36 | 37 | expect(puppeteer.launch).toHaveBeenCalledWith(expect.objectContaining({ 38 | timeout: 5000, 39 | })); 40 | }); 41 | 42 | it('should ensure custom browser options play well with default browser options', async () => { 43 | const htmlToPDF = new HTMLToPDF(basicMarkup, { 44 | browserOptions: { 45 | timeout: 9999, 46 | }, 47 | }); 48 | await htmlToPDF.convert(); 49 | 50 | expect(puppeteer.launch).toHaveBeenCalledWith(expect.objectContaining({ 51 | args: ['--font-render-hinting=none'], 52 | timeout: 9999, 53 | })); 54 | }); 55 | }); 56 | 57 | describe('createDataUri', () => { 58 | it('should convert a HTML string to base64', () => { 59 | const uri = HTMLToPDF.createDataUri('

Hello world

', 'text/html'); 60 | 61 | expect(uri).toEqual('data:text/html;base64,PHA+SGVsbG8gd29ybGQ8L3A+'); 62 | }); 63 | 64 | it('should convert a file buffer to base64', () => { 65 | const buffer = Buffer.from('

Hello world

', 'utf8'); 66 | const uri = HTMLToPDF.createDataUri(buffer, 'text/html'); 67 | 68 | expect(uri).toEqual('data:text/html;base64,PHA+SGVsbG8gd29ybGQ8L3A+'); 69 | }); 70 | }); 71 | }); 72 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export { default } from './models/HTMLToPDF'; 3 | -------------------------------------------------------------------------------- /src/models/HTMLToPDF.ts: -------------------------------------------------------------------------------- 1 | import isArray from 'lodash/fp/isArray'; 2 | import mergeWith from 'lodash/fp/mergeWith'; 3 | import puppeteer from 'puppeteer'; 4 | import { HTMLToPDFOptions } from '../types'; 5 | 6 | export default class HTMLToPDF { 7 | private _html: string; 8 | 9 | private _options: HTMLToPDFOptions = { 10 | browserOptions: { 11 | args: ['--font-render-hinting=none'], 12 | }, 13 | pdfOptions: { 14 | printBackground: true, 15 | }, 16 | waitForNetworkIdle: false, 17 | }; 18 | 19 | constructor(html: string, options?: HTMLToPDFOptions) { 20 | if (options) { 21 | this._options = this.mergeOptions(this._options, options); 22 | } 23 | this._html = html; 24 | } 25 | 26 | public set html(html: string) { 27 | this._html = html; 28 | } 29 | 30 | public set options(options: HTMLToPDFOptions) { 31 | this._options = this.mergeOptions(this._options, options); 32 | } 33 | 34 | public convert(): Promise { 35 | return new Promise(async (res, rej) => { 36 | const browser = await puppeteer.launch(this._options.browserOptions); 37 | const page = await browser.newPage(); 38 | 39 | page.on('error', async (err) => { 40 | await browser.close(); 41 | rej(err); 42 | }); 43 | 44 | if (this._options.waitForNetworkIdle) { 45 | const html = HTMLToPDF.createDataUri(this._html, 'text/html'); 46 | await page.goto(html, { waitUntil: 'networkidle0' }); 47 | } else { 48 | await page.setContent(this._html); 49 | } 50 | 51 | try { 52 | const pdf = await page.pdf(this._options.pdfOptions); 53 | await browser.close(); 54 | res(pdf); 55 | } catch (err) { 56 | await browser.close(); 57 | rej(new Error(`Error whilst generating PDF: ${err.message}`)); 58 | } 59 | }); 60 | } 61 | 62 | public static createDataUri = (data: Buffer | string, mimeType: string) => { 63 | const asBuffer = data instanceof Buffer ? data : Buffer.from(data); 64 | const asBase64 = asBuffer.toString('base64'); 65 | return `data:${mimeType};base64,${asBase64}`; 66 | }; 67 | 68 | private mergeOptions = mergeWith((objValue, srcValue) => { 69 | if (isArray(objValue)) { 70 | if (srcValue.length === 0) { 71 | return objValue = srcValue; 72 | } 73 | return objValue.concat(srcValue); 74 | } 75 | }); 76 | } 77 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Configuration for the express-html-to-pdf middleware. 3 | */ 4 | export interface HTMLToPDFOptions { 5 | /** 6 | * The Puppeteer launch options configuration. 7 | * @default { args: ['--font-render-hinting=none'] } 8 | */ 9 | browserOptions?: LaunchOptions; 10 | /** 11 | * The Puppeteer PDF options configuration. 12 | * @default { printBackground: true } 13 | */ 14 | pdfOptions?: PDFOptions; 15 | /** 16 | * By default, we assume the PDF document supplied will not contain requests over HTTP 17 | * (for fastest possible PDF generation). Typically you can embed resources by base64 18 | * encoding them as data URI's. If you have HTML that pulls assets or other resources over HTTP, 19 | * set this to true. 20 | * @default false 21 | */ 22 | waitForNetworkIdle?: boolean; 23 | } 24 | 25 | /** 26 | * Accepts values labeled with units. If number, treat as pixels. 27 | */ 28 | export type LayoutDimension = string | number; 29 | 30 | /** 31 | * Pre-defined PDF formats. 32 | */ 33 | export type PDFFormat = 34 | 'Letter' 35 | | 'Legal' 36 | | 'Tabloid' 37 | | 'Ledger' 38 | | 'A0' 39 | | 'A1' 40 | | 'A2' 41 | | 'A3' 42 | | 'A4' 43 | | 'A5'; 44 | 45 | /** 46 | * The Puppeteer PDF options configuration. 47 | */ 48 | export interface PDFOptions { 49 | /** 50 | * The file path to save the PDF to. 51 | * If `path` is a relative path, then it is resolved relative to current working directory. 52 | * If no path is provided, the PDF won't be saved to the disk. 53 | */ 54 | path?: string; 55 | /** 56 | * Scale of the webpage rendering. 57 | * @default 1 58 | */ 59 | scale?: number; 60 | /** 61 | * Display header and footer. 62 | * @default false 63 | */ 64 | displayHeaderFooter?: boolean; 65 | /** 66 | * HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: 67 | * - `date` formatted print date 68 | * - `title` document title 69 | * - `url` document location 70 | * - `pageNumber` current page number 71 | * - `totalPages` total pages in the document 72 | */ 73 | headerTemplate?: string; 74 | /** 75 | * HTML template for the print footer. Should be valid HTML markup with following classes used to inject printing values into them: 76 | * - `date` formatted print date 77 | * - `title` document title 78 | * - `url` document location 79 | * - `pageNumber` current page number 80 | * - `totalPages` total pages in the document 81 | */ 82 | footerTemplate?: string; 83 | /** 84 | * Print background graphics. 85 | * @default true 86 | */ 87 | printBackground?: boolean; 88 | /** 89 | * Paper orientation. 90 | * @default false 91 | */ 92 | landscape?: boolean; 93 | /** 94 | * Paper ranges to print, e.g., '1-5, 8, 11-13'. 95 | * @default '' which means print all pages. 96 | */ 97 | pageRanges?: string; 98 | /** 99 | * Paper format. If set, takes priority over width or height options. 100 | * @default 'Letter' 101 | */ 102 | format?: PDFFormat; 103 | /** Paper width. */ 104 | width?: LayoutDimension; 105 | /** Paper height. */ 106 | height?: LayoutDimension; 107 | /** Paper margins, defaults to none. */ 108 | margin?: { 109 | /** Top margin. */ 110 | top?: LayoutDimension; 111 | /** Right margin. */ 112 | right?: LayoutDimension; 113 | /** Bottom margin. */ 114 | bottom?: LayoutDimension; 115 | /** Left margin. */ 116 | left?: LayoutDimension; 117 | }; 118 | /** 119 | * Give any CSS @page size declared in the page priority over what is declared in width and 120 | * height or format options. 121 | * @default false which will scale the content to fit the paper size. 122 | */ 123 | preferCSSPageSize?: boolean; 124 | } 125 | 126 | /** 127 | * The Puppeteer launch options configuration. 128 | */ 129 | export interface LaunchOptions { 130 | /** 131 | * Path to a Chromium executable to run instead of bundled Chromium. If 132 | * executablePath is a relative path, then it is resolved relative to current 133 | * working directory. 134 | */ 135 | executablePath?: string; 136 | /** 137 | * Do not use `puppeteer.defaultArgs()` for launching Chromium. 138 | * @default false 139 | */ 140 | ignoreDefaultArgs?: boolean | string[]; 141 | /** 142 | * Close chrome process on Ctrl-C. 143 | * @default true 144 | */ 145 | handleSIGINT?: boolean; 146 | /** 147 | * Close chrome process on SIGTERM. 148 | * @default true 149 | */ 150 | handleSIGTERM?: boolean; 151 | /** 152 | * Close chrome process on SIGHUP. 153 | * @default true 154 | */ 155 | handleSIGHUP?: boolean; 156 | /** 157 | * Whether to pipe browser process stdout and stderr into process.stdout and 158 | * process.stderr. 159 | * @default false 160 | */ 161 | dumpio?: boolean; 162 | /** 163 | * Specify environment variables that will be visible to Chromium. 164 | * @default `process.env`. 165 | */ 166 | env?: { 167 | [key: string]: string | boolean | number; 168 | }; 169 | /** 170 | * Connects to the browser over a pipe instead of a WebSocket. 171 | * @default false 172 | */ 173 | pipe?: boolean; 174 | /** 175 | * Maximum navigation time in milliseconds, pass 0 to disable timeout. 176 | * @default 30000 177 | */ 178 | timeout?: number; 179 | /** 180 | * Whether to ignore HTTPS errors during navigation. 181 | * @default false 182 | */ 183 | ignoreHTTPSErrors?: boolean; 184 | /** 185 | * Sets a consistent viewport for each page. Defaults to an 800x600 viewport. null disables the default viewport. 186 | */ 187 | defaultViewport?: { 188 | /** 189 | * page width in pixels. 190 | */ 191 | width?: number; 192 | /** 193 | * page height in pixels. 194 | */ 195 | height?: number; 196 | /** 197 | * Specify device scale factor (can be thought of as dpr). 198 | * @default 1 199 | */ 200 | deviceScaleFactor?: number; 201 | /** 202 | * Whether the meta viewport tag is taken into account. 203 | * @default false 204 | */ 205 | isMobile?: boolean; 206 | /** 207 | * Specifies if viewport supports touch events. 208 | * @default false 209 | */ 210 | hasTouch?: boolean; 211 | /** 212 | * Specifies if viewport is in landscape mode. 213 | * @default false 214 | */ 215 | isLandscape?: boolean; 216 | } | null; 217 | /** 218 | * Slows down Puppeteer operations by the specified amount of milliseconds. 219 | * Useful so that you can see what is going on. 220 | */ 221 | slowMo?: number; 222 | /** 223 | * Whether to run browser in headless mode. 224 | * @default true unless the devtools option is true. 225 | */ 226 | headless?: boolean; 227 | /** 228 | * Additional arguments to pass to the browser instance. 229 | * The list of Chromium flags can be found here. 230 | * @default ['----font-render-hinting=none'] 231 | */ 232 | args?: string[]; 233 | /** 234 | * Path to a User Data Directory. 235 | */ 236 | userDataDir?: string; 237 | /** 238 | * Whether to auto-open a DevTools panel for each tab. 239 | * If this option is true, the headless option will be set false. 240 | */ 241 | devtools?: boolean; 242 | } 243 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "outDir": "./lib" 5 | }, 6 | "exclude": [ 7 | "**/__mocks__/*", 8 | "**/__fixtures__/*", 9 | "**/__tests__/*", 10 | "**/examples/*" 11 | ], 12 | "extends": "./tsconfig.json" 13 | } 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "esModuleInterop": true, 5 | "module": "commonjs", 6 | "strict": true, 7 | "target": "es5" 8 | } 9 | } 10 | --------------------------------------------------------------------------------