Building a Simple PDF Viewer with Node.js, Express, and PDF.js

Mohammed shamseer pv
3 min readSep 25, 2024

--

Displaying PDFs directly in a web application can greatly enhance the user experience, especially when users need to preview documents without downloading them. In this post, I will guide you through creating a simple PDF viewer using Node.js, Express, and PDF.js. This setup allows you to load and render PDF files on your webpage.

What We’ll Build

We will build a basic Express server that serves an HTML page with an embedded PDF viewer. The viewer will use PDF.js, a powerful library by Mozilla, to render PDF files inside an HTML canvas element.

Getting Started

Prerequisites

To follow along, you need to have Node.js and npm installed on your machine. If you haven’t installed them yet, you can download them from the official Node.js website.

Step 1: Setting Up the Project

Create a new directory for your project and navigate into it:

mkdir pdf-viewer
cd pdf-viewer

Initialize a new Node.js project:

npm init -y

Next, install Express:

npm install express

Step 2: Creating the Express Server

Create a file named index.js and paste the following code:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PDF Viewer</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
<style>
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: #f0f0f0;
}
#viewer {
width: 100%;
height: 100%;
overflow: auto;
}
.pdf-page {
width: 100%;
display: block;
margin: 10px 0;
border: 1px solid #ccc;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
</style>
</head>
<body>
<div id="viewer"></div>
<script>
const url = '${req.query.pdfurl}';
const pdfjsLib = window['pdfjs-dist/build/pdf'];

// Asynchronous download of PDF
const loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(pdf => {
console.log('PDF loaded');

// Loop through each page and render it
for (let pageNumber = 1; pageNumber <= pdf.numPages; pageNumber++) {
pdf.getPage(pageNumber).then(page => {
console.log('Page loaded');

const scale = 1.5;
const viewport = page.getViewport({ scale });

// Prepare canvas using PDF page dimensions
const canvas = document.createElement('canvas');
canvas.classList.add('pdf-page');
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;

// Append the canvas to the viewer
document.getElementById('viewer').appendChild(canvas);

// Render PDF page into canvas context
const renderContext = {
canvasContext: context,
viewport: viewport
};
const renderTask = page.render(renderContext);
renderTask.promise.then(() => {
console.log('Page rendered');
});
});
}
}, reason => {
console.error(reason);
});
</script>
</body>
</html>
`);
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

Step 3: Running the Server

To run your server, execute the following command in your terminal:

node index.js

Now, open your browser and navigate to http://localhost:3000/?pdfurl=<YOUR_PDF_URL>. Replace <YOUR_PDF_URL> with the URL of the PDF you want to display.

http://localhost:3000/?pdfurl=<YOUR_PDF_URL>

How the Code Works

  1. Express Setup: The Express server serves a basic HTML template when you access the root route (/).
  2. PDF.js Integration: The HTML template includes a link to the PDF.js library, which is used to fetch and render the PDF pages.
  3. Rendering Pages: PDF.js asynchronously loads the PDF document, and each page is rendered onto an HTML canvas.
  4. Viewer Layout: The viewer uses a flexible layout with some basic CSS for a simple and clean design.

--

--

Mohammed shamseer pv
Mohammed shamseer pv

Written by Mohammed shamseer pv

skilled in Flutter, Node.js, Python, and Arduino, passionate about AI and creating innovative solutions. Active in tech community projects.

No responses yet