- read

A Guide to Displaying PDFs in React JS

Jayanth babu 86

A Guide to Displaying PDFs in React JS

Jayanth babu
Level Up Coding
Published in
5 min read1 day ago

--

In the world of web applications, the ability to display PDF documents seamlessly is a common requirement. Whether you want to show user manuals, reports, or any other PDF content, React.js provides an excellent platform to achieve this. In this tutorial, we’ll explore how to display PDFs in a React.js application.

With recent upgrades in React development, create-react-app is no longer the default choice for creating React applications. Instead, it is recommended to use create-next-app as the preferred tool to initiate new React projects.

Introducing the ‘react-pdf’ Library

Before we delve into the how-tos, let’s familiarize ourselves with the ‘react-pdf’ library. It’s a React component that provides the functionality to render PDF documents within your application. Easy to integrate and lightweight, ‘react-pdf’ has emerged as a popular choice among developers for its compatibility and performance.

Setting Up Your React Project with Next.js

With the continuous evolution in React’s ecosystem, create-react-app has gradually given way to create-next-app for initiating new React projects. Here's how you can start:

  1. Installing Node.js: Ensure Node.js is set up on your machine. If not, visit the official Node.js website for download and installation instructions.
  2. Starting a New Next.js Project: Once Node.js is ready, generate a new Next.js application using the terminal:
npx create-next-app my-next-app

Replace my-next-app with the desired name for your project. This command sets up a new Next.js application with all the configurations, including routing, Webpack, and Babel. After running this command, navigate into your project’s directory and start development server.

cd my-next-app
npm run dev

Open a browser and visit http://localhost:3000. You'll be greeted by the default Next.js homepage.

Getting Started with ‘react-pdf’

First, navigate to your project’s root directory in your terminal or command prompt, and then run the following command to install the ‘react-pdf’ library:

npm install react-pdf

Step-3: Make the adjustments to ‘next.config.js’

If using Next.js, you might need some tweaks to the next.config.js for smooth canvas rendering: This step is mentioned in the official Next.js documentation to ensure proper configuration:

// next.config.js
module.exports = {
webpack: (config) => {
config.resolve.alias.canvas = false;
return config;
},
};

Step 4: Creating the PDF Viewer Component:

Here’s how you can set up a dedicated component to display your PDF:

"use client";
import { useState } from "react";
import { Document, Page, pdfjs } from "react-pdf";
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
"pdfjs-dist/build/pdf.worker.min.js",
import.meta.url,
).toString();

const PDFViewer = ({ pdfPath }) => {
const [numPages, setNumPages] = useState(null);

function onDocumentLoadSuccess({ numPages }) {
setNumPages(numPages);
}

return (
<div>
<Document file={pdfPath} onLoadSuccess={onDocumentLoadSuccess}>
{Array.from(new Array(numPages), (el, index) => (
<Page key={`page_${index + 1}`} pageNumber={index + 1} />
))}
</Document>
</div>
);
};

export default PDFViewer;

In the code above, we’ve created a PDFViewer component that accepts a pdfPath prop to dynamically load PDFs. The dynamic import from Next.js ensures this component doesn't render on the server but on the client-side, circumventing issues with the 'react-pdf' library during server-side rendering.

Step 5: Using the PDFViewer Component

Now that you’ve created the PDFViewer component, you can easily import it into your application’s pages. For example, you can use it in the app/page.js file as shown below.

import React from "react";
import PDFViewer from "./pdf-viewer";
export default function Home() {
return (
<div>
<h1>Viewing a PDF in Next.js</h1>
<PDFViewer pdfPath="./21583473018.pdf" />
</div>
);
}

Tip: Ensure your PDF files are stored in the ‘public’ folder. This special directory allows direct file access from the browser, ensuring efficient serving of assets without any Webpack processing. This means faster load times and simpler access mechanisms.

By following these steps, you can seamlessly integrate the PDFViewer component into your application’s pages and display PDFs with ease.

Step 6: Customizing the PDF Viewer

With your PDFViewer component set up, you have the flexibility to customize its appearance and enhance the user experience using ‘react-pdf’ features. You can style the viewer and add various user interactions, such as page navigation, zooming, and annotations.

Code Snippet: Adding Page Navigation, Zooming, and Annotations

"use client";
import { useState, useRef } from "react";
import { Document, Page, pdfjs } from "react-pdf";
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
"pdfjs-dist/build/pdf.worker.min.js",
import.meta.url
).toString();

const PDFViewer2 = ({ pdfPath }) => {
const [numPages, setNumPages] = useState(null);
const [pageNumber, setPageNumber] = useState(1);
const [scale, setScale] = useState(1);
const [annotations, setAnnotations] = useState([]);
const [annotationText, setAnnotationText] = useState("");
const annotationInputRef = useRef(null);

function onDocumentLoadSuccess({ numPages }) {
setNumPages(numPages);
}

return (
<div className="w-full max-w-screen-lg mx-auto p-4">
<div className="flex justify-center space-x-4 mb-4">
<button
onClick={() => setPageNumber(Math.max(1, pageNumber - 1))}
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
Previous Page
</button>
<button
onClick={() => setPageNumber(Math.min(numPages, pageNumber + 1))}
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
Next Page
</button>
<button
onClick={() => setScale(Math.min(2, scale + 0.1))}
className="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600"
>
Zoom In
</button>
<button
onClick={() => setScale(Math.max(0.5, scale - 0.1))}
className="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600"
>
Zoom Out
</button>
</div>
<div className="mb-4">
<input
type="text"
placeholder="Add annotation..."
onChange={(e) => setAnnotationText(e.target.value)}
ref={annotationInputRef}
className="w-2/3 px-4 py-2 border rounded focus:outline-none"
/>
<button
onClick={() => {
setAnnotations([
...annotations,
{ page: pageNumber, text: annotationText },
]);
setAnnotationText("");
annotationInputRef.current.value = "";
}}
className="bg-indigo-500 text-white px-4 py-2 rounded hover:bg-indigo-600"
>
Add Annotation
</button>
</div>
<Document file={pdfPath} onLoadSuccess={onDocumentLoadSuccess}>
<Page
pageNumber={pageNumber}
width={600 * scale}
/>
{annotations.map((annotation, index) =>
annotation.page === pageNumber ? (
<div
key={index}
style={{
position: "absolute",
top: 100,
left: 100,
background: "yellow",
}}
>
{annotation.text}
</div>
) : null
)}
</Document>
</div>
);
};

export default PDFViewer2;

Explanation: This code snippet demonstrates how to customize the PDF viewer’s appearance and enable user interactions. The buttons for page navigation, zooming, and adding annotations have been added to enhance the user experience. Users can navigate through pages, zoom in or out, and add annotations to the PDF. The viewer is styled using Tailwind CSS classes for an elegant and user-friendly presentation.

By implementing these features, you can create a customized and interactive PDF viewer that meets the needs of your application and provides a seamless experience for users.

Demo

How to show PDF in React js

Conclusion

By following these steps, you can create a versatile PDF viewer that allows users to navigate through PDF documents, zoom for a closer look, and annotate as needed. This tutorial provides a solid foundation for building a PDF viewer tailored to your application’s requirements.