Pre-Purchase Insights: Everything you need to know before you buy.

How to Build a PDF Viewer With Next.js

By Andy Luu | 2021 Oct 22

Sanity Image
Read time

5 min

Next.js has risen in popularity due to its numerous features that build on top of the React.js framework, such as SSR (server-side rendering). Since SSR is enabled by default for a Next.js project, it can be tricky to import and use libraries, such as Webviewer, our JavaScript PDF and Office file viewer.

If you're looking to add a library that allows you to open PDF files in a Next.js application ⁠— look no further. This guide will give you straightforward steps to add a PDF viewer to your Next.js app. The same viewer will also let you open Office files, sign, review/approve, redact, and more. (And you won’t require any Office software or MS Office licenses.)

Interested learning more about WebViewer? Check out our comprehensive Buyer's Guide here.

The source code for this project is available in our GitHub repository. You can also view our Next.js get started guide, which includes a YouTube video tutorial.


Copied to clipboard

You just need Node.js installed. That's it.

Feel free to skip ahead if you’re already a Next pro, or clone the Github repository mentioned earlier.

Install Required Packages for Your Next JS PDF Viewer

Copied to clipboard

Once you’ve installed Node.js, open up your terminal and type in the following to install create-next-app globally. It’s also available via npmjs.

npm install -g create-next-app

Now navigate to where you want the project to be created. Create and configure your project using the following command in a terminal of your choice.

npx create-next-app@latest

For this example, we stick with the defaults. If you get stuck with any of the steps, you can check out the official Next.js documentation. Navigate into your project directory and open it with your preferred code editor.

Adding the WebViewer Component

Copied to clipboard

We will now modify our Next project to add WebViewer as a component. We’ll go through each file and modification in sequence.

Install the Apryse WebViewer Package

Ensure you are in the root of your project directory. Then run:

npm i @pdftron/webviewer

Copy Static Assets

Next, we copy the static assets required for WebViewer to run. There are two ways to do this: manual and automated.

For the manual approach, locate the static assets containing WebViewer inside node_modules/@pdftron/webviewer/public and copy them to a location that will be served and publicly accessible. In Next.js, this will be the public folder. For organization, you can also create a folder called 'webviewer/lib' and place these static assets in there (for reference, view the folder structure below).

For the automated approach, modify the package.json to add two lines that will download WebViewer as a dependency to our project. To do this, find the scripts section inside of package.json and add postinstall, download-webviewer scripts that will download WebViewer:

  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next dev",
    "postinstall": "npm run download-webviewer",
    "download-webviewer": "npx @pdftron/webviewer-downloader"

By default, the WebViewer downloader will download and extract all the necessary files to public/lib. This is normally where we want them to be. However, if you would like to change the directory to ⁠— for example ⁠— public/webviewer/lib, you can do so by adding:

"download-webviewer": "npx @pdftron/webviewer-downloader --webviewerLocation ./public/webviewer/lib"

Note, it has to be inside of the public folder to preserve the folder structure. WebViewer is smart at only requesting resources when it needs to. Now, run npm install again to trigger the script and add these static assets to your project.

Also, if you clone the GitHub project and run npm install, this process is automated using the script copy-webviewer-files.js, which is a slightly different automation approach than the above, but it achieves the same result (i.e., copying static assets).

You can also download a sample PDF here and place it in a folder called /files (inside of the public folder). This is required for the next step. By now, your project structure should look something like this:

Next.js PDF Viewer project structure

Next.js PDF Viewer project structure

Add WebViewer to Index.js

Now we're ready to add WebViewer into our component. Ensure that the path property in the constructor points to where you copied the static assets from earlier (in the public folder).

import {useEffect, useRef} from 'react';

export default function HomePage() {

    const viewer = useRef(null);

    useEffect(() => {
      import('@pdftron/webviewer').then(() => {
            path: '/webviewer/lib',
            initialDoc: '/files/pdftron_about.pdf',
        ).then((instance) => {
            const { docViewer } = instance;
            // you can now call WebViewer APIs here...
    }, []);

    return (
      <div className="MyComponent">
        <div className="header">React sample</div>
        <div className="webviewer" ref={viewer} style={{height: "100vh"}}></div>

Here’s how the above code works:

The viewer variable references a DOM element, which we'll use later to initialize WebViewer.

Next, inside the useEffect lifecycle method (which gets called when the element is mounted) we call the WebViewer constructor and use the passed-in properties. Note that this is where we also import the WebViewer library, as it needs to know that the component exists first (before import) to avoid ReferenceError: window is not defined. This is because Next.js uses server-side rendering by default, which you can read more about on the official Next.js website.

When WebViewer is initialized, it returns an instance of WebViewer that can be used to call a number of useful APIs for document creation, manipulation, annotation, collaboration, redaction, and more.

Learn more about WebViewer’s comprehensive functionality by diving into the documentation. In addition, WebViewer is capable of loading files from a URL, blob, file system or base64 data.

Lastly, the style option helps us apply custom CSS like width and height on the viewer’s div element which WebViewer gets mounted on.

Run the App

We can now run our app by using:

npm run dev

or if you have yarn installed:

yarn dev

“Next” (pun intended), to view your app navigate to http://localhost:3000. That's it!


Copied to clipboard

In this blog, we showed you how to add Apryse's WebViewer using create-next-app in a few, relatively straightforward steps, to create your very own Next JS PDF Viewer that will also open Office files and do a whole lot more.

You can download the complete working sample here on GitHub.

Then, to get started with Apryse WebViewer, start a free trial. You can also check out its documentation. There, you’ll find details on WebViewer’s many supported features and on how to customize the WebViewer UI to your desired look and feel.

If you have any questions about integrating Apryse into your Next project (ha ha) or want to learn more about our complete PDF SDK, please feel free to contact us. We’ll be more than happy to help!

Sanity Image

Andy Luu

Share this post