Print React components in the browser
npm install react-to-print



Print the content of a React component.
npm install --save react-to-print

``tsx
import { useReactToPrint } from "react-to-print";
import { useRef } from "react";
const contentRef = useRef
const reactToPrintFn = useReactToPrint({ contentRef });
return (
It is also possible to lazy set the ref if your content being printed is dynamic. See the
LazyContent example for more. This can also be useful for setting the ref in non-React code, such as util functions.API
| Option | Type | Description |
| :-------------------: | :------- | :---------------------------------------------------------------------------------------------------------------------------------- |
|
bodyClass | string | One or more class names to pass to the print window, separated by spaces |
| contentRef | React.RefObject | The ref pointing to the content to be printed. Alternatively, pass the ref directly to the callback returned by useReactToPrint |
| copyShadowRoots | boolean | Copy shadow root content into the print window. Warning: Use with care if you print large documents as traversing these can be slow. |
| documentTitle | string | Set the title for printing when saving as a file |
| fonts | { family: string, source: string; weight?: string; style?: string; }[] | A list of fonts to load into the printing iframe. This is useful if you are using custom fonts |
| ignoreGlobalStyles | boolean | Ignore all $3
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 property. Check caniuse to see if the browsers you develop against support this.`css
@media print {
@page {
size: 50mm 150mm;
}
}
`$3
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.
$3
In the component that is passed in as the content ref, add the following:
`css
@media print {
@page { size: landscape; }
}
`$3
Instead of using
{ display: 'none'; }, try using { overflow: hidden; height: 0; }$3
pageStyle should be a CSS string. For example: ".divider { break-after: always; }"$3
Many have found setting the following CSS helpful. See #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;
}
}
`Another thing to try, especially if you are seeing this issue on mobile browsers, is to set
preserveAfterPrint: true as it's possible the browser is causing the print iframe to be removed before printing has completed.$3
We often (#327, #343, #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. Some newer versions of libraries have specific tools for dealing with printing, for example, Bootstrap 4's Display property.$3
What to know:
break-inside (replaces page-break-inside)
- break-before (replaces page-break-before)
- break-after (replaces 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 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$3

If you need to print the content of a scrolling container, you may encounter the following issues:
- Unable to control the scroll position, so the printed content may not be what you want.
- Overflow content is truncated, resulting in missing printed content.
To solve these problems, you need to modify the properties of the scrolling container when printing. You can pass a function to the
print property, which will be called when printing. In this function, you can use the DOM API to query the scrolling container that needs to be modified, and then modify its properties to control the scroll position.`javascript
const customToPrint = (printWindow) => {
const printContent = printWindow.contentDocument || printWindow.contentWindow?.document;
const printedScrollContainer = printContent.querySelector('.scroll-container'); const originScrollContainer = document.querySelector('.scroll-container');
// Set the scroll position of the printed container to match the origin container
printedScrollContainer.scrollTop = originScrollContainer.scrollTop;
// You can also set the
overflow and height properties of the printed container to show all content.
// printedScrollContainer.style.overflow = "visible";
// printedScrollContainer.style.height = "fit-content"; printWindow.contentWindow.print();
}
const handlePrint = useReactToPrint({
// ...
print: customToPrint,
});
`#### Simple Show All Content
In addition to the methods in the above example, you can also simply add a CSS class name to the scrolling container when printing to show all content.
Set the container to
overflow: visible; height: fit-content when printing, cancel the scrolling behavior when the content overflows, and make the height adapt to the content.`css
@media print {
.scroll-container {
overflow: visible;
height: fit-content;
}
}
`> Note:
>
> - If the styles do not take effect, you can try using the
!important modifier.
> - The styles provided in the above instructions are for reference only. Complex situations may require more styles to achieve the desired result.Running locally
NOTE: The library is built and tested locally using Node ^20.
- Clone the repo
-
npm ci
- npm start`- vue-to-print: vue3 version of react-to-print