Browse by type

Print the content of a React component.
npm install --save react-to-print
import { useReactToPrint } from "react-to-print";
import { useRef } from "react";
const contentRef = useRef<HTMLDivElement>(null);
const reactToPrintFn = useReactToPrint({ contentRef });
return (
<button onClick={reactToPrintFn}>Print</button>
Content to print
);
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.
| Option | Type | Description |
|---|---|---|
bodyClass |
string |
One or more class names to pass to the print window, separated by spaces |
contentRef |
React.RefObject<Element \| Text> |
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 <style> and <link type="stylesheet" /> tags |
nonce |
string |
Set the nonce attribute for allow-listing script and style elements for Content Security Policy (CSP) |
onAfterPrint |
() => void |
Callback function that triggers after the print dialog is closed regardless of if the user selected to print or cancel |
onBeforePrint |
() => Promise<void> |
Callback function that triggers before print. This can be used to change the content on the page before printing as an alternative to, or in conjunction with, @media print queries |
onPrintError |
(errorLocation: 'onBeforePrint' \| 'print', error: Error) => void |
Called if there is a printing error serious enough that printing cannot continue. Currently limited to Promise rejections in onBeforePrint, and print. |
pageStyle |
string |
react-to-print sets some basic styles to help improve page printing, notably, removing the header and footer that most browsers add. Use this to override these styles and provide your own |
preserveAfterPrint |
boolean |
Preserve the print iframe after printing. This can be useful for debugging by inspecting the print iframe |
print |
(iframe: HTMLIFrameElement) => Promise<void> |
If passed, this function will be used instead of window.print to print the content. Use this to print in non-browser environments such as Electron |
printIframeProps |
{ allow?: string, referrerPolicy?: HTMLAttributeReferrerPolicy, sandbox?: string } |
Allows setting certain properties of the print iframe, primarily for privacy and security policies |
suppressErrors |
boolean |
When passed, prevents console logging of errors |
react-to-print should be compatible with most modern browsers.
While printing on mobile browsers generally works, printing within a WebView (when your page is opened by an app such as Facebook or Slack, but not by the full browser itself) is known to generally not work. Some WebViews don't make the correct API available. Others make it available but cause printing to no-op.
We are actively researching resolutions to this issue, but it likely requires changes by Google/Chromium and Apple/WebKit. See #384 for more information. If you know of a way we can solve this your help would be greatly appreciated.
window.print)onAfterPrint may fire immediately (before the print dialog is closed) on newer versions of Safari where window.print does not blockType 'undefined' is not assignable to type 'ReactInstance | null'.. You likely need to set your ref to initially be null: useRef(null)documentTitle will not work if react-to-print is run within an iframe. If react-to-print is run within an iframe and your script has access to the parent document, you may be able to manually set and then restore the parent document's title during the print. This can be done by leveraging the onBeforePrint and onAfterPrint callbacks.
When printing, only styles that directly target the printed nodes will be applied as the parent nodes of the printed nodes will not exist in the print DOM. For example, in the code below, if the `
tag is the root of theComponentToPrint` then the red styling will not be applied. Be sure to target all printed content directly and not from unprinted parents.
```jsx
Hello
```
css
div.parent p { color:red; }
The connect method from react-redux returns a functional component that cannot be assigned a reference to be used within the contentRef. To use a component wrapped in connect within contentRef, create an intermediate component that simply renders your component wrapped in connect. See 280 for more.
When rendering multiple components to print, ensure each is passed a unique ref. Then, either use a unique useReactToPrint call for each component, or, using a single useReactToPrint call pass the refs at print-time to the printing function returned by the hook. If you share refs across components only the last component will be printed. See 323 for more.
The simplest way to hide or show content during printing is to use a CSS Media Query.
.printContent {
display: none;
@media print {
display: block;
}
}
const contentRef = useRef<HTMLDivElement>(null);
const reactToPrintFn = useReactToPrint({ contentRef });
return (
<button onClick={reactToPrintFn}>Print</button>
Content to print
);
react-to-print be used to download a PDF without using the Print Preview window?Not directly. We aren't able to print a PDF as we lose control once the print preview window opens. However, it is possible to use react-to-print to gather the content you want to print and pass it to a library that can generate a PDF.
const handlePrint = useReactToPrint({
...,
print: async (printIframe: HTMLIframeElement) => {
// Do whatever you want here, including asynchronous work
await generateAndSavePDF(printIframe);
},
});
For examples of how others have done this, see #484
react-to-print be used to change the settings within the print preview dialog?No. The window.print API does not provide a way to change these settings. Only various CSS hints can be provided, with each browser potentially treating them differently.
ComponentToPrint be a Class component?Not directly. To print a Class based component you will need to manually forward the contentRef as a prop:
class ComponentToPrint extends Component {
render() {
return (
Print content
)
}
}
function App {
const contentRef = useRef(null);
const handlePrint = useReactToPrint({ contentRef });
return (
<button onClick={handlePrint}>Print</button>
<ComponentToPrint innerRef={contentRef} />
);
}
onAfterPrint fire even if the user cancels printingonAfterPrint fires when the print dialog closes, regardless of why it closes. This is the behavior of the onafterprint browser event.
react-to-print skip <link rel="stylesheet" href=""> tags<link>s with empty href attributes are invalid HTML. In addition, they can cause all sorts of undesirable behavior. For example, many browsers - including modern ones, when presented with <link href=""> will attempt to load the current page. Some even attempt to load the current page's parent directory.
Note: related to the above, img tags with empty src attributes are also invalid, and we may not attempt to load them.
ComponentToPrint show only while printingIf you've created a component that is intended only for printing and should not render in the parent component, wrap that component in a div with style set to { display: "none" }, like so:
<ComponentToPrint ref={componentRef} />
This will hide ComponentToPrint but keep it in the DOM so that it can be copied for printing.
onBeforePrintRecall that setting state is asynchronous. As such, you need to pass a Promise and wait for the state to update.
const [isPrinting, setIsPrinting] = useState(false);
const contentRef = useRef(null);
// We store the resolve Promise being used in `onBeforePrint` here
const promiseResolveRef = useRef(null);
// We watch for the state to change here, and for the Promise resolve to be available
useEffect(() => {
if (isPrinting && promiseResolveRef.current) {
// Resolves the Promise, letting `react-to-print` know that the DOM updates are completed
promiseResolveRef.current();
}
}, [isPrinting]);
const handlePrint = useReactToPrint({
contentRef,
onBeforePrint: () => {
return new Promise((resolve) => {
promiseResolveRef.current = resolve;
setIsPrinting(true);
});
},
onAfterPrint: () => {
// Reset the Promise resolve so we can print again
promiseResolveRef.current = null;
setIsPrinting(false);
}
});
Note: for Class components, pass the Promise resolve to the callback for this.setState: this.setState({ isPrinting: false }, resolve)
Unfortunately there is no standard browser API for interacting with the print dialog. All react-to-print is able to do is open the dialog and give it the desired content to print. We cannot modify settings such as the default paper size, if the user has background graphics selected or not, etc.
video elementsreact-to-print tries to wait for video elements to load before printing but a large part of this is up to the browser. Further, the image displayed will usually be the first frame of the video, which might not be what you expect to show. To ensure the proper image is displayed in the print we highly recommend setting the poster attribute of the video, which allows specifying an image to be a placeholder for the video until the video loads.
react-to-print can be used for printing in Electron, but you will need to provide your own print method since Electron does not natively support the window.print method. Please see this answer on StackOverflow for how to do this.
There is a fully-working example of how to use react-to-print with Electron available here.
link elements not displaying styles properlySome frameworks such as Ruby on Rails will set media="screen" on <link> elements that don't have screen set. This can cause styles to appear incorrectly when printing. To fix, explicitly set media="screen" on your <link> elements. For <link> elements meant to apply only when printing, set media="print".
While you should be able to place these styles anywhere, sometimes the browser doesn't always pick them up. To force orientation of the page you can include the following in the component being printed:
<style type="text/css" media="print">{"\
@page {\ size: landscape;\ }\
"}</style>
The default page size is usually A4. Most brow
$ claude mcp add react-to-print \
-- python -m otcore.mcp_server <graph>