Open a PDF in React on the Web with react-pdf

In previous articles, I discussed simple options for opening a PDF in your web app without JavaScript and how to render PDF files in the browser with PDF.js.
Today, I’m going one step further and will examine how you can open a PDF in a React application on the web. React is a popular JavaScript library for building user interfaces on the web, as well as with a multitude of other systems, including iOS and Android.
In this article, we’ll use react-dom
and focus on the web. If you’re looking for a React Native guide, check out our blog post on how to open a PDF in React Native.
Getting Started
For this article, you’ll be using a library by Wojciech Maj called react-pdf
. If you use your favorite online search engine, you’ll likely find another library with the same name, created by Diego Muracciole. However, at the time of writing, the latter is only used to create PDFs.
react-pdf
provides a React-based component API for opening PDF files and rendering them using PDF.js.
To get started, you’ll set up a minimal React application using Create React App. This makes it so you don’t have to think about configuration (alternatively, you can take a look at the fantastic React documentation and learn about ways to get started without using any additional tooling). To do this, run the following:
yarn create react-app pdf-app cd pdf-app yarn start
npx create-react-app pdf-app cd pdf-app npm start
After these commands are run, your favorite browser will open, and you’ll see the boilerplate generated by Create React App.
Rendering a PDF in React
To start rendering your first PDF, place the file you want to render inside the ./public
directory of the pdf-app
folder. This ensures you can access the file from the web.
Next, add react-pdf
to your project:
yarn add react-pdf
npm install react-pdf
react-pdf
comes with two components that are of interest when rendering a PDF: Document
and Page
. Document
is used to open a PDF and is a mandatory part. Within the document, you can mount pages, which are used to render the PDF page. To integrate this into your example project, open ./src/App.js
and replace its contents with the following:
import React, { Component } from 'react'; import { Document, Page } from 'react-pdf'; export default class App extends Component { state = { numPages: null, pageNumber: 1 }; onDocumentLoadSuccess = ({ numPages }) => { this.setState({ numPages }); }; goToPrevPage = () => this.setState((state) => ({ pageNumber: state.pageNumber - 1 })); goToNextPage = () => this.setState((state) => ({ pageNumber: state.pageNumber + 1 })); render() { const { pageNumber, numPages } = this.state; return ( <div> <nav> <button onClick={this.goToPrevPage}>Prev</button> <button onClick={this.goToNextPage}>Next</button> </nav> <div style={{ width: 600 }}> <Document file="/example.pdf" onLoadSuccess={this.onDocumentLoadSuccess} > <Page pageNumber={pageNumber} width={600} /> </Document> </div> <p> Page {pageNumber} of {numPages} </p> </div> ); } }
This is already enough to render a PDF in React.
Since react-pdf
doesn’t come with a user interface, you’ve built your own. In the example above, you render two buttons to navigate the page within the <nav>
elements and show the total progress on the bottom. The result looks something like this:
Enabling Advanced PDF Features in react-pdf
By default, react-pdf
enables important features of PDF.js — including the text layer, which allows you to copy and paste text from the PDF. However, one feature that’s disabled is the dedicated annotation layer. In a PDF, annotations provide additional information and enable the use of hyperlinks. In the example PDF, there’s a hyperlink on the first page that you want to enable as well. To do this, import an additional file for the CSS that’s needed:
import 'react-pdf/dist/Page/AnnotationLayer.css';

Another improvement you can make is to use web workers so that your PDFs can be rendered in another thread. This keeps the main window responsive at all times. Luckily, react-pdf
comes with pre-built support for adding this option to webpack, and Create React App uses webpack under the hood.
To enable web workers, replace your input line with the following:
import React, { Component } from "react"; - import { Document, Page } from "react-pdf"; + import { Document, Page } from "react-pdf/dist/entry.webpack"; import "react-pdf/dist/Page/AnnotationLayer.css";
You can see the worker in action by inspecting the page with your favorite developer tools.

Conclusion
With just a few lines of code, you were able to utilize the full power of PDF.js in a React application. This is a great and low-cost way to get started with simple use cases. For more complex use cases, a commercial React PDF library can provide additional benefits:
-
An out-of-the-box PDF viewer UI to help speed up development time. Quickly deploy a polished UI in your application and use well-documented APIs to customize the design and layout.
-
Embed prebuilt PDF tools to easily add functionality like annotating documents, editing PDFs, adding digital signatures to a PDF form, and much more.
-
View multiple file types — from image files (JPG, PNG, TIFF) to MS Office documents.
-
Get a quick response from a dedicated support team if you encounter a challenge or issue when integrating the viewer.
At PSPDFKit, we offer a commercial, feature-rich, and completely customizable JavaScript PDF library that’s easy to integrate and comes with well-documented APIs to handle advanced use cases. Try it for free, and visit our demo to see it in action, or check out our example application to learn more.