Blog Post

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

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

In previous articles, you learned about options for opening a PDF in your web app without JavaScript and how to render PDF files in the browser with PDF.js.

Today, you’ll go one step further and examine how to 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, you’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:

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:

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 { useState } from 'react';
import { Document, Page } from 'react-pdf';

const App = () => {
	const [numPages, setNumPages] = useState(null);
	const [pageNumber, setPageNumber] = useState(1);

	const onDocumentLoadSuccess = ({ numPages }) => {
		setNumPages(numPages);
	};

	const goToPrevPage = () => setPageNumber((prevPage) => prevPage - 1);
	const goToNextPage = () => setPageNumber((prevPage) => prevPage + 1);

	return (
		<div>
			<nav>
				<button onClick={goToPrevPage}>Prev</button>
				<button onClick={goToNextPage}>Next</button>
			</nav>

			<div style={{ width: 600 }}>
				<Document
					file="/example.pdf"
					onLoadSuccess={onDocumentLoadSuccess}
				>
					<Page pageNumber={pageNumber} width={600} />
				</Document>
			</div>

			<p>
				Page {pageNumber} of {numPages}
			</p>
		</div>
	);
};

export default App;

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 what’s shown below.

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 a 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';
Screenshot of a PDF page with a link annotation

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 prebuilt 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.

Screenshot of Chrome DevTools showing the web worker in action

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:

  1. An out-of-the-box PDF viewer user interface (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.

  2. Embed prebuilt PDF tools to easily add functionality like annotating documents, editing PDFs, adding digital signatures to a PDF form, and much more.

  3. View multiple file types — from image files (JPG, PNG, TIFF) to MS Office documents.

  4. 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.

Share Post
Free 60-Day Trial Try PSPDFKit in your app today.
Free Trial

Related Articles

Explore more
PRODUCTS  |  Web • Releases • Components

PSPDFKit for Web 2024.3 Features New Stamps and Signing UI, Export to Office Formats, and More

PRODUCTS  |  Web • Releases • Components

PSPDFKit for Web 2024.2 Features New Unified UI Icons, Shadow DOM, and Tab Ordering

PRODUCTS  |  Web

Now Available for Public Preview: New Document Authoring Experience Provides Glimpse into the Future of Editing