This article was first published in September 2021 and was updated in November 2024.
In this blog post, you’ll learn how to build a React.js PDF viewer using the react-pdf
library. react-pdf
is a widely used open source library designed specifically for rendering PDF files in React applications. This library leverages the power of PDF.js, a popular open source project by Mozilla, to parse and render PDF documents in the browser.
In the first part of this blog post, you’ll look at how to create the PDF viewer with react-pdf
, and in the second part, you’ll be able to follow along with a guide on how to integrate the Nutrient React.js PDF viewer library into a React.js project.
Open source React.js PDF viewer libraries
There are a couple of open source React PDF viewer libraries. One of the most popular is the @react-pdf/renderer
library, with 510K weekly downloads on npm. It’s used for creating PDF files in the browser, on the server, or on mobile devices. If you want to work with this library, please refer to our How to Create a PDF with React.js blog post.
Another popular library is react-pdf
by Wojciech Maj, with around 950K weekly downloads on npm. It’s used to display existing PDFs. This library will be used in this blog for the purpose of creating a PDF viewer.
The information about react-pdf
is mostly correct and captures the main features of the library well. However, there are a few clarifications to ensure accuracy:
-
Components (
Document
andPage
): TheDocument
component is indeed used for loading PDF files, andPage
components represent individual pages of the PDF. For best practices, it is indeed recommended to define configuration options outside of the component (such as usinguseMemo
) to optimize performance, especially when re-renders occur. -
Lack of Built-in UI as a Feature: This is accurate.
react-pdf
does not include a built-in UI, allowing developers to create custom controls and integrate them with the library’s functionality to match their design needs. -
Compatibility with React’s Ecosystem: This statement is accurate. Being a React-specific library,
react-pdf
is built to integrate well with React’s hooks, context, and other features, providing a seamless experience. -
Community Support: Mentioning the library’s popularity is valid. It is well-supported, with an active community and documentation, which provides a good level of support and resources.
Why Choose react-pdf
?
react-pdf
is an excellent choice for developers who want to integrate PDF viewing functionality into their React applications. Here are some key benefits:
-
Ease of Integration:
react-pdf
offers a simple and straightforward API, making it easy to add PDF viewing capabilities to existing React projects. You can quickly display PDFs with minimal setup. -
Flexibility: The library provides components like
Document
andPage
, enabling developers to create custom PDF viewers. TheDocument
component is essential for loading PDF files, and for optimized performance, it is recommended to define any configuration options outside the React component, using hooks likeuseMemo
. -
Customization: While
react-pdf
doesn’t include a built-in UI, this flexibility allows you to create a user interface tailored to your application’s design. You can add navigation controls, zoom functionality, and other features using standard React components. -
Compatibility: As a pure React library,
react-pdf
is fully compatible with the React ecosystem. Whether you’re using hooks, context, or other React features,react-pdf
integrates seamlessly. -
Community Support: With around 950K weekly downloads on npm,
react-pdf
has a large and active community. This means you can find ample resources, examples, and support from other developers who use the library.
Requirements to get started
To get started, you’ll need:
-
A package manager compatible with npm. This guide contains usage examples for Yarn and the npm client (installed with Node.js by default). Make sure the
npm
version is 5.6 or greater.
Building a React.js PDF viewer with react-pdf
Start by creating a React.js project with vite
:
npm create vite@latest react-pdf-demo -- --template react
After the project is created, change the directory into the project folder:
cd react-pdf-demo
Adding react-pdf
-
Now, you can install the npm package for the
react-pdf
library from the terminal:
npm install react-pdf
-
Place the file you want to render inside the
public
directory of thereact-pdf-example
project. You can use our demo document as an example; you just need to rename it todocument.pdf
.
Displaying a PDF
-
react-pdf
comes with two components:Document
andPage
.Document
is used to open a PDF and is mandatory. Within the document, you can mount pages, which are used to render the PDF page. To integrate this into your example project, opensrc/App.jsx
and replace its contents with the following:
import { useState } from 'react'; import { Document, Page } from 'react-pdf'; // Text layer for React-PDF. import 'react-pdf/dist/Page/TextLayer.css'; const App = () => { const [numPages, setNumPages] = useState(null); const [pageNumber, setPageNumber] = useState(1); const onDocumentLoadSuccess = ({ numPages }) => { setNumPages(numPages); }; const goToPrevPage = () => setPageNumber(pageNumber - 1 <= 1 ? 1 : pageNumber - 1); const goToNextPage = () => setPageNumber( pageNumber + 1 >= numPages ? numPages : pageNumber + 1, ); return ( <div> <nav> <button onClick={goToPrevPage}>Prev</button> <button onClick={goToNextPage}>Next</button> <p> Page {pageNumber} of {numPages} </p> </nav> <Document file="pspdfkit-web-demo.pdf" onLoadSuccess={onDocumentLoadSuccess} > <Page pageNumber={pageNumber} /> </Document> </div> ); }; export default App;
For react-pdf
to work, a PDF.js worker needs to be provided. You can do this in a couple of ways. For most cases, importing the worker will work as was done in the src/App.jsx
file:
import { pdfjs } from 'react-pdf'; pdfjs.GlobalWorkerOptions.workerSrc = new URL( 'pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url, ).toString(); // Rest of code.
You can read more about how to configure a PDF.js worker in your project here.
-
Now, start the application by running the following:
npm run dev
One of the disadvantages of using react-pdf
is that it doesn’t come with a UI. In this example, you’ve rendered two buttons to navigate between pages and showed the total number of pages.
You can access the full code on GitHub.
Limitations of react-pdf
Overall, react-pdf
is a great open source project, but it has some disadvantages:
- It doesn’t come with a user interface out of the box. If you need a UI to help users navigate through a PDF, you’ll need to build it from scratch.
- Text selection doesn’t work properly. If you try to select text in a PDF, you’ll see that it’s not a good user experience.
- Rendering large PDF files or documents with many pages can sometimes impact performance, particularly in resource-constrained environments.
Building a React.js PDF viewer with Nutrient
We offer a commercial React.js PDF library that can easily be integrated into your web application. It comes with 30+ features that let you view, annotate, edit, and sign documents directly in your browser. Out of the box, it has a polished and flexible UI that you can extend or simplify based on your unique use case.
- A prebuilt and polished UI
- 15+ annotation tools
- Support for multiple file types
- Dedicated support from engineers
Creating a new React project
-
Use
vite
to scaffold out a simple React application:
npm create vite@latest pspdfkit-react-example -- --template react
-
Change to the created project directory:
cd pspdfkit-react-example
Adding Nutrient to your project
-
Now, add Nutrient Web SDK as a dependency:
npm install pspdfkit
-
As you’re using the WebAssembly build of Nutrient Web SDK, the final setup step is to copy files the browser will need from the
npm
module:
cp -R ./node_modules/pspdfkit/dist/pspdfkit-lib public/pspdfkit-lib
The code above will copy the pspdfkit-lib
directory from within node_modules/
into the public/
directory to make it available to the SDK at runtime.
-
Make sure your
public
directory contains apspdfkit-lib
directory with the Nutrient library assets.
Displaying a PDF
-
Add the PDF document you want to display to the
public
directory. You can use our demo document as an example. -
Add a component wrapper for the Nutrient library and save it as
src/components/ViewerComponent.jsx
:
import { useEffect, useRef } from 'react'; export default function ViewerComponent(props) { const containerRef = useRef(null); useEffect(() => { const container = containerRef.current; let PSPDFKit; (async function () { PSPDFKit = await import('pspdfkit'); PSPDFKit.unload(container); await PSPDFKit.load({ // Container where PSPDFKit should be mounted. container, // Use dark theme. theme: PSPDFKit.Theme.DARK, // The document to open. document: props.document, // Use the public directory URL as a base URL. PSPDFKit will download its library assets from here. baseUrl: `${window.location.protocol}//${ window.location.host }/${import.meta.env.BASE_URL}`, }); })(); return () => PSPDFKit && PSPDFKit.unload(container); }, [props.document]); return ( <div ref={containerRef} style={{ width: '100%', height: '100vh' }} /> ); }
To load Nutrient Web SDK into the ViewerComponent
, use PSPDFKit.load
when the component has mounted.
-
Now, all that’s left is to render the
ViewerComponent
inApp.jsx
by loading the PDF you downloaded earlier:
import ViewerComponent from './components/ViewerComponent'; function App() { return ( <div className="App" style={{ width: '100vw' }}> <div className="App-viewer"> <ViewerComponent document={'document.pdf'} /> </div> </div> ); } export default App;
-
You can also open a different PDF file by adding a button and adding a handler to the
onClick
event:
// App.jsx import { useState } from 'react'; import ViewerComponent from './components/ViewerComponent'; function App() { const [document, setDocument] = useState('document.pdf'); const handleOpen = () => setDocument('another-example.pdf'); return ( <div className="App" style={{ width: '100vw' }}> <button className="App-button" onClick={handleOpen}> Open another document </button> <div className="App-viewer"> <ViewerComponent document={document} /> </div> </div> ); } export default App;
You can use this example document as a second example. Rename it to another-example.pdf
, and then add it to the /public
folder.
When you click Open another document, it loads the another-example.pdf
file.
-
Your project structure will now look like this:
pspdfkit-react-example ├── public │ ├── pspdfkit-lib │ └── document.pdf │ └── another-example.pdf ├── src │ ├── components │ | └── ViewerComponent.jsx | └── App.js └── package.json
-
Start the app and run it in your default browser:
npm run dev
You’ll now see your PDF rendered in the container
element. Try using the toolbar to navigate through, annotate, and search in the document. Note that because Nutrient is a commercial product, you’ll see a Nutrient Web SDK evaluation notice on the document. To get a license key, contact Sales.
You can find the finished code on GitHub.
If you hit any snags, don’t hesitate to reach out to our Support team for help.
Adding even more capabilities
Once you’ve deployed your viewer, you can start customizing it to meet your specific requirements or easily add more capabilities. To help you get started, here are some of our most popular React.js guides:
- Adding annotations
- Editing documents
- Filling PDF forms
- Adding signatures to documents
- Real-time collaboration
- Redaction
- UI customization
Conclusion
In this post, you first saw how to build a React.js PDF viewer with the react-pdf
library. In the second half, you walked through how to deploy the Nutrient React.js PDF viewer.
You can also deploy our vanilla JavaScript PDF viewer or use one of our many web framework deployment options like Vue.js, Angular, and jQuery. To see a list of all web frameworks, start your free trial. Or, launch our demo to see our viewer in action.
FAQ
Here are a few frequently asked questions about building a PDF viewer in React.js.
How can I create a PDF viewer in React.js using react-pdf?
You can create a PDF viewer in React.js by installing thereact-pdf
library, importing its components, and using the Document
and Page
components to render PDF files.
What are the main components of the react-pdf library?
The main components are:Document
: Used for loading the PDF file.Page
: Used for rendering individual pages of the PDF.
PDF.js
library to display PDF content.
How do I install and set up react-pdf in a React project?
Installreact-pdf
using npm with the command:
npm install @react-pdf-viewer/react-pdf
Then, set up your project by:
- Importing the necessary components from the library.
- Configuring the
PDF.js
worker file to ensure proper rendering. - Using the
Document
andPage
components to display your PDF.
What are the limitations of the react-pdf library?
Some limitations ofreact-pdf
include:
- It lacks a built-in user interface for navigation or other controls.
- Text selection can sometimes be inconsistent.
- Users need to manually build features like zoom, search, and navigation controls.
How can I enhance the functionality of a React.js PDF viewer?
You can enhance the functionality by:- Building custom UI controls such as navigation, zoom, and search functionality.
- Integrating libraries like
Nutrient
to add advanced features like annotations, form filling, and enhanced user interface components.