Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-pdf-html

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-pdf-html

Html component for react-pdf with CSS support

  • 2.1.3
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
41K
increased by15.89%
Maintainers
1
Weekly downloads
 
Created
Source

react-pdf-html

<Html> component for react-pdf

  • Support for CSS via <style> tags and style attributes (limited to Style properties supported by react-pdf)
  • Browser CSS defaults with option for style reset
  • Basic <table>(attempted using flex layouts) <ul> and <ol> support
  • Ability to provide custom renderers for any tag
  • Support for inline <style> tags and remote stylesheets (using fetch)

How it Works

  1. Parses the HTML string into a JSON tree of nodes using node-html-parser
  2. Parses any <style> tags in the document and style attributes using css-tree
  3. Renders all nodes using the appropriate react-pdf components, applying cascading styles for each node as an array passed to the style prop:
    • block/container nodes using <View>
    • inline/text nodes using <Text>, with appropriate nesting and collapsing of whitepace
    • <img> nodes using <Image>
    • <a> nodes using <Link>

Installation

npm i react-pdf-html

OR

yarn add react-pdf-html

Usage

import Html from 'react-pdf-html';

const html = `<html>
  <body>
    <style>
      .my-heading4 {
        background: darkgreen;
        color: white;
      }
      pre {
        background-color: #eee;
        padding: 10px;
      }
    </style>
    <h1>Heading 1</h1>
    <h2 style="background-color: pink">Heading 2</h2>
    <h3>Heading 3</h3>
    <h4 class="my-heading4">Heading 4</h4>
    <p>
      Paragraph with <strong>bold</strong>, <i>italic</i>, <u>underline</u>,
      <s>strikethrough</s>,
      <strong><u><s><i>and all of the above</i></s></u></strong>
    </p>
    <p>
      Paragraph with image <img src="${myFile}" /> and
      <a href="http://google.com">link</a>
    </p>
    <hr />
    <ul>
      <li>Unordered item</li>
      <li>Unordered item</li>
    </ul>
    <ol>
      <li>Ordered item</li>
      <li>Ordered item</li>
    </ol>
    <br /><br /><br /><br /><br />
    Text outside of any tags
    <table>
      <thead>
        <tr>
          <th>Column 1</th>
          <th>Column 2</th>
          <th>Column 3</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Foo</td>
          <td>Bar</td>
          <td>Foobar</td>
        </tr>
        <tr>
          <td colspan="2">Foo</td>
          <td>Bar</td>
        </tr>
        <tr>
          <td>Some longer thing</td>
          <td>Even more content than before!</td>
          <td>Even more content than before!</td>
        </tr>
      </tbody>
    </table>
    <div style="width: 200px; height: 200px; background: pink"></div>
    <pre>
function myCode() {
  const foo = 'bar';
}
</pre>
  </body>
</html>
`;

return (
  <Document>
    <Page>
      <Html>{html}</Html>
    </Page>
  </Document>
);

Rendering React Components

import ReactDOMServer from 'react-dom/server';

const element = (
  <html>
    <body>
      <style>
        {`
        .heading4 {
          background: darkgreen;
          color: white;
        }
        pre {
          background-color: #eee;
          padding: 10px;
        }`}
      </style>
      <h1>Heading 1</h1>
      <h2 style={{ backgroundColor: 'pink' }}>Heading 2</h2>
      ...
    </body>
  </html>
);

const html = ReactDOMServer.renderToStaticMarkup(element);

return (
  <Document>
    <Page>
      <Html>{html}</Html>
    </Page>
  </Document>
);

Props

type HtmlProps = {
  children: string; // the HTML
  collapse?: boolean; // Default: true. Collapse whitespace. If false, render newlines as breaks
  renderers?: HtmlRenderers; // Mapping of { tagName: HtmlRenderer }
  style?: Style | Style[]; // Html root View style
  stylesheet?: HtmlStyles | HtmlStyles[]; // Mapping of { selector: Style }
  resetStyles?: false; // If true, style/CSS reset
};

Overriding Element Styles

Provide a Stylesheet

const stylesheet = {
  // clear margins for all <p> tags
  p: {
    margin: 0,
  },
  // add pink background color to elements with class="special"
  ['.special']: {
    backgroundColor: 'pink',
  },
};

return (
  <Document>
    <Page>
      <Html stylesheet={stylesheet}>{html}</Html>
    </Page>
  </Document>
);

Inline Styles

const html = `<div style="width: 200px; height: 200px; background-color: pink">Foobar</div>`;

return (
  <Document>
    <Page>
      <Html>{html}</Html>
    </Page>
  </Document>
);

Remote Styles

Remote styles must be resolve asynchronously, outside of the React rendering, because react-pdf doesn't support asynchronous rendering

import { fetchStylesheets } from 'react-pdf-html';

const html = `<html>
  <head>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
      integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
      crossorigin="anonymous" />
  </head>

  <body>
    <div></div>
  </body>
</html>`;

const stylesheets = await fetchStylesheets(html, {
    ...fetchOptions
});

...

return (
  <Document>
    <Page>
      <Html stylesheet={stylesheets}>{html}</Html>
    </Page>
  </Document>
);

Resetting Styles

Reset browser default styles (see CSS reset)

return (
  <Document>
    <Page>
      <Html resetStyles>{html}</Html>
    </Page>
  </Document>
);

Font Sizes

The default styesheet roughly matches browser defaults, using a rough emulation of ems:

const em = (em: number, relativeSize: number = fontSize) => em * relativeSize;

StyleSheet.create({
  h1: {
    fontSize: em(2),
    marginVertical: em(0.67, em(2)),
    fontWeight: 'bold',
  },
  ...
});

By default, the basis for the font size ems is based on the fontSize from props.style:

return (
  <Document>
    <Page>
      <Html style={{ fontSize: 10 }}>{html}</Html>
    </Page>
  </Document>
);

If this is not defined, it falls back to a default of 18

Fonts for bold, italic, etc.

Please 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:

Font.register({
  family: 'OpenSans',
  fonts: [
    { src: fonts + '/Open_Sans/OpenSans-Regular.ttf' },
    { src: fonts + '/Open_Sans/OpenSans-Bold.ttf', fontWeight: 'bold' },
    { src: fonts + '/Open_Sans/OpenSans-Italic.ttf', fontStyle: 'italic' },
    {
      src: fonts + '/Open_Sans/OpenSans-BoldItalic.ttf',
      fontWeight: 'bold',
      fontStyle: 'italic',
    },
  ],
});

Keywords

FAQs

Package last updated on 15 Jan 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc