react-to-print logo

# ReactToPrint - Print React components in the browser [![NPM Downloads](https://img.shields.io/npm/dt/react-to-print.svg?style=flat)](https://npmcharts.com/compare/react-to-print?minimal=true) [![npm version](https://badge.fury.io/js/react-to-print.svg)](https://badge.fury.io/js/react-to-print) So you've created a React component and would love to give end users the ability to print out the contents of that component. This package aims to solve that by popping up a print window with CSS styles copied over as well. ## Demo [![Run react-to-print](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/rzdhd) ## Install `npm install --save react-to-print` ## API ### <ReactToPrint /> The component accepts the following props: | Name | Type | Description | | :-------------------: | :------- | :---------------------------------------------------------------------------------------------------------------------------------- | | **`bodyClass?`** | `string` | One or more class names to pass to the print window, separated by spaces | | **`content`** | `function` | A function that returns a component reference value. The content of this reference value is then used for print | | **`copyStyles?`** | `boolean` | Copy all ` ``` ### Set the page size The default page size is usually A4. Most browsers do not allow JavaScript or CSS to set the page size. For the browsers that do, it is usually done using the CSS page [`size`](https://developer.mozilla.org/en-US/docs/Web/CSS/@page/size) property. Check [`caniuse`](https://caniuse.com/mdn-css_at-rules_page_size) to see if the browsers you develop against support this. ```css @media print { @page { size: 50mm 150mm; } } ``` ### Set custom margin to the page ([29](https://github.com/gregnb/react-to-print/issues/29)) To set custom margin to the page, First, create a function to return the page margin, ```js const getPageMargins = () => { return `@page { margin: ${marginTop} ${marginRight} ${marginBottom} ${marginLeft} !important; }`; }; ``` Now, within the JSX call this function within the style tags, ```jsx ``` PS: This style tag should be inside the component that is being passed in as the content ref. ### Set landscape printing ([240](https://github.com/gregnb/react-to-print/issues/240)) In the component that is passed in as the content ref, add the following: ```css @media print { @page { size: landscape; } } ``` ### Printing elements that are not displayed ([159](https://github.com/gregnb/react-to-print/issues/159)) Instead of using `{ display: 'none'; }`, try using `{ overflow: hidden; height: 0; }` ### Using the `pageStyle` prop The `pageStyle` prop should be a CSS string. For example: `".divider { break-after: always; }"` ### Getting a blank page when printing Many have found setting the following CSS helpful. See [#26](https://github.com/gregnb/react-to-print/issues/26) for more. ```css @media print { html, body { height: 100vh; /* Use 100% here to support printing more than a single page*/ margin: 0 !important; padding: 0 !important; overflow: hidden; } } ``` #### When you've set the `removeAfterPrint` prop to `true` If you are getting a blank page while setting `removeAfterPrint` to `true`, try setting it to `false`. This will tell the browser not to remove the `iframe` that we use to print, which it may be doing by mistake, especially on mobile browsers. ### Styles incorrect in print dialog when using grid system We often ([#327](https://github.com/gregnb/react-to-print/issues/327), [#343](https://github.com/gregnb/react-to-print/issues/343), [#382](https://github.com/gregnb/react-to-print/issues/382)) see issues reported where the developer is using Bootstrap or a similar grid system, and everything works great until the user goes to print and suddenly it seems the styles are off. We've found that often the issue is the grid library uses the smallest sized columns during printing, such as the `xs` size on Bootstrap's grid, a size developers often don't plan for. The simplest solution is to ensure your grid will adapt to this size appropriately, though this may not be acceptable since you may want the large view to print rather than the smaller view. Another solution is to [override the grid column definition](https://stackoverflow.com/questions/22199429/bootstrap-grid-for-printing/28152320). Some newer versions of libraries have specific tools for dealing with printing, for example, [Bootstrap 4's Display property](https://getbootstrap.com/docs/4.3/utilities/display/). ### Page Breaks What to know: - [`break-inside`](https://developer.mozilla.org/en-US/docs/Web/CSS/break-inside) (replaces [`page-break-inside`](https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-inside)) - [`break-before`](https://developer.mozilla.org/en-US/docs/Web/CSS/break-before) (replaces [`page-break-before`](https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-before)) - [`break-after`](https://developer.mozilla.org/en-US/docs/Web/CSS/break-after) (replaces [`page-break-after`](https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-after)) #### Pattern for Page-Breaking Dynamic Content Define a page-break class to apply to elements which could be sensibly split into a page. ```html
{listOfContent.map(yourContent => ( <>
{yourContent}
)}
``` In your styles, define your `@media print` styles, which should include setting your preference for CSS `page-break-` (see [w3's reference](https://www.w3schools.com/cssref/pr_print_pageba.asp) for options) to `auto`, and ensuring that your `page-break` element does not affect non-print styles. ```css @media all { .page-break { display: none; } } @media print { html, body { height: initial !important; overflow: initial !important; -webkit-print-color-adjust: exact; } } @media print { .page-break { margin-top: 1rem; display: block; page-break-before: auto; } } @page { size: auto; margin: 20mm; } ``` #### Troubleshooting Page Breaks If your content rendered as print media does not automatically break multi-page content into multiple pages, the issue may be - Style incompatibilities with print media rendering - A need to assign `CSS page-break-` properties to define how your document should behave when printed #### Common Page Break Pitfalls - A style of `overflow: scroll`, when rendered to print, will result in cut off content instead of page breaks to include the content - A style of `position: absolute`, when rendered to print, may result in reformatted, rotated, or re-scaled content, causing unintended affects to print page layout and page breaks - Using `flex` may interfere with page breaks, try using `display: block` ## Running locally *NOTE*: Node >=12 is required to build the library locally. We use Node ^14 for our tests.