{"id":14483636,"url":"https://github.com/danomatic/react-pdf-html","last_synced_at":"2025-04-10T06:19:05.915Z","repository":{"id":38391422,"uuid":"375152983","full_name":"danomatic/react-pdf-html","owner":"danomatic","description":"Render HTML in react-pdf","archived":false,"fork":false,"pushed_at":"2025-01-15T17:40:37.000Z","size":1106,"stargazers_count":186,"open_issues_count":34,"forks_count":42,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-03T04:08:12.399Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/danomatic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2021-06-08T21:45:05.000Z","updated_at":"2025-03-24T22:50:28.000Z","dependencies_parsed_at":"2024-02-17T05:24:09.642Z","dependency_job_id":"2fe29dc6-4731-4863-a794-a7b6bbf94883","html_url":"https://github.com/danomatic/react-pdf-html","commit_stats":{"total_commits":79,"total_committers":6,"mean_commits":"13.166666666666666","dds":"0.10126582278481011","last_synced_commit":"41b44cf582e69492d0f5a9beac1a0f68493e9650"},"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danomatic%2Freact-pdf-html","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danomatic%2Freact-pdf-html/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danomatic%2Freact-pdf-html/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danomatic%2Freact-pdf-html/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danomatic","download_url":"https://codeload.github.com/danomatic/react-pdf-html/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248166864,"owners_count":21058481,"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":[],"created_at":"2024-09-03T00:01:56.160Z","updated_at":"2025-04-10T06:19:05.897Z","avatar_url":"https://github.com/danomatic.png","language":"TypeScript","readme":"# react-pdf-html\n\n`\u003cHtml\u003e` component for [react-pdf](https://github.com/diegomura/react-pdf/)\n\n- Support for CSS via `\u003cstyle\u003e` tags and `style` attributes (limited to `Style` properties supported by `react-pdf`)\n- [Browser CSS defaults](https://www.w3schools.com/cssref/css_default_values.asp) with option for [style reset](https://meyerweb.com/eric/tools/css/reset/)\n- Basic `\u003ctable\u003e`(attempted using flex layouts) `\u003cul\u003e` and `\u003col\u003e` support\n- Ability to provide custom renderers for any tag\n- Support for inline `\u003cstyle\u003e` tags and remote stylesheets (using fetch)\n\n## How it Works\n\n1. Parses the HTML string into a JSON tree of nodes using [node-html-parser](https://github.com/taoqf/node-html-parser)\n2. Parses any `\u003cstyle\u003e` tags in the document and `style` attributes using [css-tree](https://github.com/csstree/csstree)\n3. Renders all nodes using the appropriate `react-pdf` components, applying cascading styles for each node as an array passed to the `style` prop:\n   - block/container nodes using `\u003cView\u003e`\n   - inline/text nodes using `\u003cText\u003e`, with appropriate nesting and collapsing of whitepace\n   - `\u003cimg\u003e` nodes using `\u003cImage\u003e`\n   - `\u003ca\u003e` nodes using `\u003cLink\u003e`\n\n## Installation\n\n```bash\nnpm i react-pdf-html\n```\n\nOR\n\n```bash\nyarn add react-pdf-html\n```\n\n## Usage\n\n```tsx\nimport Html from 'react-pdf-html';\n\nconst html = `\u003chtml\u003e\n  \u003cbody\u003e\n    \u003cstyle\u003e\n      .my-heading4 {\n        background: darkgreen;\n        color: white;\n      }\n      pre {\n        background-color: #eee;\n        padding: 10px;\n      }\n    \u003c/style\u003e\n    \u003ch1\u003eHeading 1\u003c/h1\u003e\n    \u003ch2 style=\"background-color: pink\"\u003eHeading 2\u003c/h2\u003e\n    \u003ch3\u003eHeading 3\u003c/h3\u003e\n    \u003ch4 class=\"my-heading4\"\u003eHeading 4\u003c/h4\u003e\n    \u003cp\u003e\n      Paragraph with \u003cstrong\u003ebold\u003c/strong\u003e, \u003ci\u003eitalic\u003c/i\u003e, \u003cu\u003eunderline\u003c/u\u003e,\n      \u003cs\u003estrikethrough\u003c/s\u003e,\n      \u003cstrong\u003e\u003cu\u003e\u003cs\u003e\u003ci\u003eand all of the above\u003c/i\u003e\u003c/s\u003e\u003c/u\u003e\u003c/strong\u003e\n    \u003c/p\u003e\n    \u003cp\u003e\n      Paragraph with image \u003cimg src=\"${myFile}\" /\u003e and\n      \u003ca href=\"http://google.com\"\u003elink\u003c/a\u003e\n    \u003c/p\u003e\n    \u003chr /\u003e\n    \u003cul\u003e\n      \u003cli\u003eUnordered item\u003c/li\u003e\n      \u003cli\u003eUnordered item\u003c/li\u003e\n    \u003c/ul\u003e\n    \u003col\u003e\n      \u003cli\u003eOrdered item\u003c/li\u003e\n      \u003cli\u003eOrdered item\u003c/li\u003e\n    \u003c/ol\u003e\n    \u003cbr /\u003e\u003cbr /\u003e\u003cbr /\u003e\u003cbr /\u003e\u003cbr /\u003e\n    Text outside of any tags\n    \u003ctable\u003e\n      \u003cthead\u003e\n        \u003ctr\u003e\n          \u003cth\u003eColumn 1\u003c/th\u003e\n          \u003cth\u003eColumn 2\u003c/th\u003e\n          \u003cth\u003eColumn 3\u003c/th\u003e\n        \u003c/tr\u003e\n      \u003c/thead\u003e\n      \u003ctbody\u003e\n        \u003ctr\u003e\n          \u003ctd\u003eFoo\u003c/td\u003e\n          \u003ctd\u003eBar\u003c/td\u003e\n          \u003ctd\u003eFoobar\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n          \u003ctd colspan=\"2\"\u003eFoo\u003c/td\u003e\n          \u003ctd\u003eBar\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n          \u003ctd\u003eSome longer thing\u003c/td\u003e\n          \u003ctd\u003eEven more content than before!\u003c/td\u003e\n          \u003ctd\u003eEven more content than before!\u003c/td\u003e\n        \u003c/tr\u003e\n      \u003c/tbody\u003e\n    \u003c/table\u003e\n    \u003cdiv style=\"width: 200px; height: 200px; background: pink\"\u003e\u003c/div\u003e\n    \u003cpre\u003e\nfunction myCode() {\n  const foo = 'bar';\n}\n\u003c/pre\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n`;\n\nreturn (\n  \u003cDocument\u003e\n    \u003cPage\u003e\n      \u003cHtml\u003e{html}\u003c/Html\u003e\n    \u003c/Page\u003e\n  \u003c/Document\u003e\n);\n```\n\n## Rendering React Components\n\n```tsx\nimport ReactDOMServer from 'react-dom/server';\n\nconst element = (\n  \u003chtml\u003e\n    \u003cbody\u003e\n      \u003cstyle\u003e\n        {`\n        .heading4 {\n          background: darkgreen;\n          color: white;\n        }\n        pre {\n          background-color: #eee;\n          padding: 10px;\n        }`}\n      \u003c/style\u003e\n      \u003ch1\u003eHeading 1\u003c/h1\u003e\n      \u003ch2 style={{ backgroundColor: 'pink' }}\u003eHeading 2\u003c/h2\u003e\n      ...\n    \u003c/body\u003e\n  \u003c/html\u003e\n);\n\nconst html = ReactDOMServer.renderToStaticMarkup(element);\n\nreturn (\n  \u003cDocument\u003e\n    \u003cPage\u003e\n      \u003cHtml\u003e{html}\u003c/Html\u003e\n    \u003c/Page\u003e\n  \u003c/Document\u003e\n);\n```\n\n## Props\n\n```ts\ntype HtmlProps = {\n  children: string; // the HTML\n  collapse?: boolean; // Default: true. Collapse whitespace. If false, render newlines as breaks\n  renderers?: HtmlRenderers; // Mapping of { tagName: HtmlRenderer }\n  style?: Style | Style[]; // Html root View style\n  stylesheet?: HtmlStyles | HtmlStyles[]; // Mapping of { selector: Style }\n  resetStyles?: false; // If true, style/CSS reset\n};\n```\n\n## Overriding Element Styles\n\n### Provide a Stylesheet\n\n```tsx\nconst stylesheet = {\n  // clear margins for all \u003cp\u003e tags\n  p: {\n    margin: 0,\n  },\n  // add pink background color to elements with class=\"special\"\n  ['.special']: {\n    backgroundColor: 'pink',\n  },\n};\n\nreturn (\n  \u003cDocument\u003e\n    \u003cPage\u003e\n      \u003cHtml stylesheet={stylesheet}\u003e{html}\u003c/Html\u003e\n    \u003c/Page\u003e\n  \u003c/Document\u003e\n);\n```\n\n### Inline Styles\n\n```tsx\nconst html = `\u003cdiv style=\"width: 200px; height: 200px; background-color: pink\"\u003eFoobar\u003c/div\u003e`;\n\nreturn (\n  \u003cDocument\u003e\n    \u003cPage\u003e\n      \u003cHtml\u003e{html}\u003c/Html\u003e\n    \u003c/Page\u003e\n  \u003c/Document\u003e\n);\n```\n\n### Remote Styles\n\nRemote styles must be resolve asynchronously, outside of the React rendering,\nbecause react-pdf doesn't support asynchronous rendering\n\n```tsx\nimport { fetchStylesheets } from 'react-pdf-html';\n\nconst html = `\u003chtml\u003e\n  \u003chead\u003e\n    \u003clink\n      rel=\"stylesheet\"\n      href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css\"\n      integrity=\"sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN\"\n      crossorigin=\"anonymous\" /\u003e\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    \u003cdiv\u003e\u003c/div\u003e\n  \u003c/body\u003e\n\u003c/html\u003e`;\n\nconst stylesheets = await fetchStylesheets(html, {\n    ...fetchOptions\n});\n\n...\n\nreturn (\n  \u003cDocument\u003e\n    \u003cPage\u003e\n      \u003cHtml stylesheet={stylesheets}\u003e{html}\u003c/Html\u003e\n    \u003c/Page\u003e\n  \u003c/Document\u003e\n);\n```\n\n## Resetting Styles\n\nReset browser default styles (see [CSS reset](https://meyerweb.com/eric/tools/css/reset/))\n\n```tsx\nreturn (\n  \u003cDocument\u003e\n    \u003cPage\u003e\n      \u003cHtml resetStyles\u003e{html}\u003c/Html\u003e\n    \u003c/Page\u003e\n  \u003c/Document\u003e\n);\n```\n\n## Font Sizes\n\nThe default styesheet roughly matches browser defaults, using a rough emulation of ems:\n\n```tsx\nconst em = (em: number, relativeSize: number = fontSize) =\u003e em * relativeSize;\n\nStyleSheet.create({\n  h1: {\n    fontSize: em(2),\n    marginVertical: em(0.67, em(2)),\n    fontWeight: 'bold',\n  },\n  ...\n});\n```\n\nBy default, the basis for the font size ems is based on the `fontSize` from `props.style`:\n\n```tsx\nreturn (\n  \u003cDocument\u003e\n    \u003cPage\u003e\n      \u003cHtml style={{ fontSize: 10 }}\u003e{html}\u003c/Html\u003e\n    \u003c/Page\u003e\n  \u003c/Document\u003e\n);\n```\n\nIf this is not defined, it falls back to a default of `18`\n\n## Fonts for bold, italic, etc.\n\nPlease note that `react-pdf` has some constraints with how fonts are applied (see https://react-pdf.org/fonts). You must provide a different font file for each combination of bold, italic, etc. For example:\n\n```ts\nFont.register({\n  family: 'OpenSans',\n  fonts: [\n    { src: fonts + '/Open_Sans/OpenSans-Regular.ttf' },\n    { src: fonts + '/Open_Sans/OpenSans-Bold.ttf', fontWeight: 'bold' },\n    { src: fonts + '/Open_Sans/OpenSans-Italic.ttf', fontStyle: 'italic' },\n    {\n      src: fonts + '/Open_Sans/OpenSans-BoldItalic.ttf',\n      fontWeight: 'bold',\n      fontStyle: 'italic',\n    },\n  ],\n});\n```\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanomatic%2Freact-pdf-html","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanomatic%2Freact-pdf-html","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanomatic%2Freact-pdf-html/lists"}