Skip to content

Basic Usage

Anatomy

The following structure demonstrates how to build a React PDF by importing and assembling components. This modular approach gives you the flexibility to customize the viewer as needed.

<RPConfig> {/* Configuration license and pdfjs-dist worker */}
<RPProvider> {/* Viewer context provider */}
<RPTheme> {/* Theme customization (optional) */}
<RPDefaultLayout> {/* Default layout container */}
<RPPages /> {/* PDF pages renderer */}
</RPDefaultLayout>
</RPTheme>
</RPProvider>
</RPConfig>

Remark: For more information on what each part is, please refer to Component.

Basic Implementation

The most basic usage of React PDF needs four components, namely: RPConfig, RPProvider, RPDefaultLayout, and RPPages.

Here’s how to implement a basic PDF viewer in a React application:

  1. Place <RPConfig> at the root of your React application. This component should only be used once in your application.

    src/App.jsx
    import { RPConfig } from '@pdf-viewer/react'
    function App() {
    ...
    return (
    <>
    <RPConfig licenseKey={YOUR_LICENSE_KEY}>
    ...
    </RPConfig>
    </>
    )
    }
    export default App
  2. Create a reusable PDF viewer component that encapsulates the core functionality:

    src/components/AppPdfViewer.jsx
    import { RPProvider, RPDefaultLayout, RPPages } from '@pdf-viewer/react'
    const AppPdfViewer = () => {
    return (
    <RPProvider src="https://cdn.codewithmosh.com/image/upload/v1721763853/guides/web-roadmap.pdf">
    <RPDefaultLayout>
    <RPPages />
    </RPDefaultLayout>
    </RPProvider>
    )
    }
    export default AppPdfViewer

    The PDF viewer will automatically adjust to fit its container’s dimensions. You can adjust the dimensions by setting the style prop in RPDefaultLayout.

  3. Now, you can use AppPdfViewer anywhere in your React application. Here is an example of using it in the homepage:

    src/App.jsx
    import { RPConfig } from '@pdf-viewer/react'
    import AppPdfViewer from './AppPdfViewer'
    function App() {
    ...
    return (
    <>
    <RPConfig licenseKey={YOUR_LICENSE_KEY}>
    ...
    <AppPdfViewer />
    </RPConfig>
    </>
    )
    }
    export default App

Key Points

  • The viewer requires at minimum: RPConfig, RPProvider, RPDefaultLayout, and RPPages
  • Set dimensions using the style prop on RPDefaultLayout
  • For Next.js, always use client-side rendering with dynamic import
  • The viewer is responsive and will adapt to its container size

Handling Source of PDF File

The src prop of the RPProvider component is designed for flexibility, accepting different types of PDF sources. This allows developers to handle PDFs from various origins, such as URLs, file paths within the project, or Blob objects (e.g., when fetching files from an API). Below is a detailed guide on how to handle each type of source effectively.

URL (HTTP/HTTPS)

If the src prop is a URL, the component can directly fetch and display the PDF. This is useful for displaying PDFs hosted on an external server.

Example
<RPConfig>
<RPProvider src="https://cdn.codewithmosh.com/image/upload/v1721763853/guides/web-roadmap.pdf">
<RPDefaultLayout>
<RPPages />
</RPDefaultLayout>
</RPProvider>
</RPConfig>

Best Practices:

  • Ensure the URL is accessible and the server supports CORS (Cross-Origin Resource Sharing) if the PDF is hosted on a different domain.

Blob (From API or File Upload)

If the src prop is a Blob URL (e.g., blob:https://example.com/pdf-document), it can be used to display generated PDFs or fetch PDFs dynamically such as from a file upload or an API.

Example
// Fetch PDF from an API
const [pdfBlobUrl, setPdfBlobUrl] = useState(null)
const [error, setError] = useState(null)
const [isLoading, setIsLoading] = useState(true)
useEffect(() => {
const fetchPdf = async () => {
try {
// Fetch PDF from the API
const response = await fetch('https://api.example.com/document')
if (!response.ok) {
throw new Error('Failed to fetch PDF')
}
// Convert the response to a Blob
const blob = await response.blob()
// Generate a Blob URL
const blobUrl = URL.createObjectURL(blob)
// Update state with the Blob URL
setPdfBlobUrl(blobUrl)
} catch (err) {
// Handle errors
setError(err.message)
} finally {
// Set loading to false
setIsLoading(false)
}
}
// Call the fetch function
fetchPdf()
// Cleanup function to revoke the Blob URL when the component unmounts
return () => {
if (pdfBlobUrl) {
URL.revokeObjectURL(pdfBlobUrl)
}
}
}, []) // Empty dependency array ensures this runs only once on mount
return (
<RPConfig>
<RPProvider src={pdfBlobUrl}>
<RPDefaultLayout>
<RPPages />
</RPDefaultLayout>
</RPProvider>
</RPConfig>
)

Best Practices:

  • Always revoke Blob URLs using URL.revokeObjectURL when the component is destroyed or the Blob is no longer needed to prevent memory leaks
  • Handle errors during the fetch operation and provide fallback content or error messages

Internal File Path

Vite

When using Vite, you have two main approaches to handle PDF files:

  1. Import in JavaScript: You can directly import PDF files in your JavaScript modules. Vite will resolve the path during the build process. This is ideal for PDFs bundled with your application:
Example
import pdfFile from './assets/document.pdf'
return (
<RPConfig>
<RPProvider src={pdfFile}>
<RPDefaultLayout>
<RPPages />
</RPDefaultLayout>
</RPProvider>
</RPConfig>
)
  1. Serve from Public Folder: If you prefer to keep your PDFs in the public folder, you can serve them directly from there:
Example
<RPConfig>
<RPProvider src="/document.pdf">
<RPDefaultLayout>
<RPPages />
</RPDefaultLayout>
</RPProvider>
</RPConfig>

Best Practices:

  • Use new URL('./path/to/file.pdf', import.meta.url).href for importing PDFs as URLs
  • Place PDFs in src/assets for processing through Vite’s asset pipeline
  • Configure vite.config.js to handle PDF files:
vite.config.js
export default {
assetsInclude: ['**/*.pdf']
}