🚀 How to Build a React PDF Viewer for Next.js in Minutes

Kittisak MaKittisak Ma
7 min read

Since my last post on Best 4 Methods to Build a PDF Viewer in React.js: PDF.js, react-pdf, and More, my team and I launched React PDF in March 2025, a library that help React developers easily add a React PDF viewer to their Next.js apps.

In this article, I'll show you how to display the default PDF Viewer in Next.js in just a few steps. I'll also share a few use cases to help you make the most out of React PDF in your own projects.


Why React PDF?

React PDF

If you’re building a PDF viewer in a Next.js app, you need a component that just works. React PDF stands out for its balance of powerful features and simple setup. You can drop it into your Next.js project with little work and handles most of what React devs expect. Its API feels natural if you know React, so no relearning is required.

React PDF offers everything most apps need right out of the box. Here’s what you get:

  1. React-First: Designed specifically for React.js developers, React PDF uses familiar component-based patterns, and hooks fit right in with your Next.js app’s structure.

  2. Customizable: You can style or customize easily. From changing icons and colors to match your branding or customize your toolbar layout with React Context APIs to fit your app's needs.

  3. Responsive Design: Fits devices big or small, so mobile users can scroll, zoom, and interact with ease.

  4. High Performance: Optimized for handling large PDFs without sacrificing speed or performance.

  5. No surprises: The documentation is clear, and support is strong. Bugs get addressed fast. Most developers will find everything they need quickly.


Step 1: Set up a Next.js Project

In this tutorial, I'll use StackBlitz to demonstrate how to build a React PDF Viewer in a Next.js project. Here's how to get started.

1.1 Visit StackBlitz & Create a New Project

Go to https://stackblitz.com. Assuming you already have an account and are logged in, click “New Project” in the top-right corner. You’ll see a list of available frameworks—select Next.js.

StackBlitz - New Project frameworks

1.2 Wait for StackBlitz to Set Things Up

StackBlitz will automatically install the necessary dependencies and launch your Next.js project in the browser.

StackBlitz - Next.js project

That’s it! You're now ready to integrate React PDF Viewer into your StackBlitz-based Next.js project.


Step 2: Integrate React PDF into a Next.js Project

2.1 Install React PDF

First, install the @pdf-viewer/react package in your project. In the StackBlitz terminal, press Ctrl + C to stop the current process, then run the following command:

npm install @pdf-viewer/react

Wait for the installation to complete. This should only take a few seconds.

StackBlitz's terminal - install the react pdf viewer

2.2 Set Up the Viewer

After installing, follow these steps to set up the PDF viewer:

đź’ˇ Pro Tip: Always use client-side rendering for these components using dynamic imports to prevent hydration mismatches and SSR-related issues with PDF rendering.

Add RPConfig at the Root Level

The RPConfig component provides the global configuration for React PDF and should wrap your entire app.

Place the RPConfig component at the root of your application (e.g., in _app.tsx or a root layout component). Make sure it only runs on the client side.

components/AppProviders.tsx

'use client';
import { RPConfig, RPConfigProps } from '@pdf-viewer/react';
import { type PropsWithChildren } from 'react';

function AppProviders({
  children,
  ...props
}: PropsWithChildren<RPConfigProps>) {
  return <RPConfig {...props}>{children}</RPConfig>;
}
export default AppProviders;

components/LazyAppProviders.tsx

'use client';
import dynamic from 'next/dynamic';

const LazyAppProviders = dynamic(() => import('./AppProviders'), {
  ssr: false,
});
export default LazyAppProviders;

app/layout.tsx

import { type PropsWithChildren } from 'react'
import LazyAppProviders from './components/LazyAppProviders'

export default function RootLayout({ children }: PropsWithChildren) {
 return (
   <html lang="en">
     <body>
      <LazyAppProviders licenseKey="your-license-key">
        <main>
          { children }
        </main>
      </LazyAppProviders>
    </body>
   </html>
 )
}

Step 3: Create a Reusable PDF Viewer Component

To keep your code clean and reusable, it’s a good practice to wrap the viewer in its own component. This also makes it easier to customize or extend the viewer later as your app grows.

Build the AppPdfViewer component

components/AppPdfViewer.tsx

'use client'
import { RPProvider, RPDefaultLayout, RPPages } from '@pdf-viewer/react'

interface OwnProps {
 src: string
}

const AppPdfViewer = (props: OwnProps) => {
 const { src } = props
   return (
     <RPProvider src={ src }>
       <RPDefaultLayout>
         <RPPages />
       </RPDefaultLayout>
     </RPProvider>
   )
}

export default AppPdfViewer

Create a Lazy-Loaded Wrapper Component

Since React PDF is client-side only, we’ll also create a lazy wrapper to prevent SSR issues and hydration errors in Next.js.

components/LazyAppPdfViewer.tsx

'use client'
import dynamic from 'next/dynamic'

const LazyAppPdfViewer = dynamic(() => import('./AppPdfViewer'), {
 ssr: false
})
export default LazyAppPdfViewer

Use the PDF Viewer in Your App

You can now use LazyAppPdfViewer anywhere in your Next.js application.

Here's an example of how to use it on the index page:

app/index.tsx

import LazyAppPdfViewer from '../components/LazyAppPdfViewer';

export default function Home() {
  const pdfUrl = "https://cdn.codewithmosh.com/image/upload/v1721763853/guides/web-roadmap.pdf"
  return (
   ...
   <div className="pdf-viewer mb-3 w-[500px] lg:w-[992px]">
    <LazyAppPdfViewer src={ pdfUrl } />
   </div>
   ...
  )
}

That’s it! You should now see your PDF in action.

React PDF Viewer on Stackblitz

Note: At the moment, Hot Module Reload (HMR) does not apply css style automatically to a component that dynamically import with ssr: false. It is recommended to refresh the page after changing the component.


Looking for a Faster Setup?

If you want to skip boilerplate and get straight to building, check out the React PDF Starter Toolkit.

It includes ready-to-use templates for:

  • React (Vite / Webpack)

  • Next.js (JavaScript / TypeScript)

Each template comes with a clean folder structure and sample code so you can build a PDF viewer quickly without spending hours configuring dependencies. Just clone, customize, and go. 🚀


Common Use Cases

Customize the PDF Viewer to Match Your Branding

Every project has its own look and feel. @pdf-viewer/react makes it easy to tailor the PDF viewer’s appearance so it fits right into your app — whether it’s light mode, dark mode, or a custom color palette.

With the customVariables prop in the RPTheme component, you can quickly apply brand colors to the viewer without digging into complex CSS overrides.

Here’s a simple example of applying a custom background color:

...
const AppPdfViewer = (props: OwnProps) => {
 const { src } = props
   return (
     <RPProvider src={ src }>
       <RPTheme
          customVariables={{ '--rp-toolbar-background': '#F7E3D5' }}
          customDarkVariables={{ '--rp-toolbar-background': '#874707' }}
        >
         <RPDefaultLayout>
           <RPPages />
         </RPDefaultLayout>
       </RPTheme>
     </RPProvider>
   )
}

export default AppPdfViewer

Light Mode

React PDF Viewer with light mode customization

Dark Mode

React PDF Viewer with dark mode customization

Why this is useful:

  • Provides a consistent branded experience

  • Works out of the box with theme switching (light/dark mode)

  • Saves time styling PDF viewers for modern UIs

Customize Any Toolbar Icon

The @pdf-viewer/react component offers flexibility in customizing the user interface. You can easily replace any default icons with your own, allowing you to maintain brand consistency or match with the rest of your application’s UI.

Here’s an example of how to replace the default toolbar icons in @pdf-viewer/react with Lucide Icons, allowing for a more customized and consistent user interface.

To get started, install the Lucide Icons package:

npm install lucide-react

Once installed, you can import and use Lucide icons to replace the default icons in @pdf-viewer/react.

...
const AppPdfViewer = (props: OwnProps) => {
  const { src } = props;
  const defaultIconDimension = { width: 20, height: 20 };
  return (
   ...
    <RPDefaultLayout
      icons={{
        zoomInIcon: <ZoomInIcon {...defaultIconDimension} />,
        zoomOutIcon: <ZoomOutIcon {...defaultIconDimension} />,
        downloadIcon: <DownloadIcon {...defaultIconDimension} />,
        searchIcon: <SearchIcon {...defaultIconDimension} />,
        ...
      }}
    >
      <RPPages />
    </RPDefaultLayout>
   ...
  )
}
...

At this point, all of the viewer's toolbar icons have been successfully replaced.

React PDF Viewer - toolbar icon customization

If you'd like to see the example code in action, check out my StackBlitz for this article.

Want to learn more about the library? Check out the documentation or jump right into our live demo!


Conclusion

Adding a PDF viewer to your Next.js app is simple with React PDF viewer. The setup takes just a few steps, and you instantly get a flexible, fast and robust tool. The viewer works responsively across different devices and screen sizes. You can easily style it to match your app’s look or let users zoom in and jump to pages without any hassle.

React PDF is a great choice for:

  • Simple PDF reading experiences

  • Document workflows and approval systems

  • AI-powered tools that need to display PDFs

  • Business and productivity apps with embedded documents

It takes care of PDF rendering behind the scenes — so you can focus on building great features your users want.

Try it out and see how easy it is to upgrade your project’s PDF viewing experience! 🚀

👉 Want to explore more? Check out the full React PDF documentation and live demo to see what else you can build.

If you found this helpful, let me know! And if you build something cool with React PDF, I’d love to hear about it.

0
Subscribe to my newsletter

Read articles from Kittisak Ma directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Kittisak Ma
Kittisak Ma