Build a Vite PDF viewer with Apryse WebViewer SDK

This guide shows how to build a Vite PDF viewer using the Apryse WebViewer SDK. You’ll learn how to integrate the SDK into React, Vanilla, Vue, or Svelte applications to render, view, and interact with PDF documents in the WebViewer UI.

For more, explore the interactive Showcase demo to see WebViewer's full capabilities in action.

Prerequisites

This guide assumes basic familiarity with Vite development. Before you start:

License Key

Apryse collects some data regarding your usage of the SDK for product improvement.

If you wish to continue without data collection, contact us and we will email you a no-tracking trial key for you to get started.

1. Create a Vite project

In this section, you’ll create a new Vite application using npm. This project provides the foundation for integrating Apryse WebViewer. If you already have a React app, skip this and continue to Install WebViewer.

  1. In your terminal, go to the directory where you want to create the project.
  2. Create a new webviewer-vite project using a minimal setup:

Shell

1npm create vite@latest webviewer-vite -- --template react

Info

Flags are used to skip prompts during project configuration. These flags determine which framework is used and select JavaScript as the variant. Select different options if preferred.

3. If prompted to install with npm and start now, select No.

4. Navigate to your new Vite project directory and install dependencies:

Shell

1cd webviewer-vite
2npm install

2. Install WebViewer

Next, install the Apryse WebViewer SDK using npm. This command adds the WebViewer package to your project, allowing you to integrate the PDF viewer and editor into your Vite application.

After navigating to your webviewer-vite project directory, run the following command to install WebViewer:

Shell

1npm i @pdftron/webviewer

3. Copy WebViewer assets

WebViewer needs access to its static assets at runtime, including WebAssembly modules, HTML, and CSS files. In a Vite project, you must copy these assets into the public directory so they can be served correctly. We'll use a Vite plugin to copy WebViewer's static assets into the public folder. For more, see Copying WebViewer static assets.

  1. From your project directory, run the following to install the vite-plugin-static-copy package:

Shell

1npm i -D vite-plugin-static-copy

2. In Visual Studio Code, update the vite.config.js file to import the viteStaticCopy plugin and save. If you don't see a vite.config.js file in your project, create one at the project root and add the necessary configuration:

JavaScript

vite.config.js

1import { defineConfig } from 'vite';
2import react from '@vitejs/plugin-react';
3import { viteStaticCopy } from 'vite-plugin-static-copy';
4
5// https://vite.dev/config/
6export default defineConfig({
7 plugins: [
8 react(),
9 viteStaticCopy({
10 targets: [
11 {
12 src: 'node_modules/@pdftron/webviewer/public/**/*',
13 dest: 'lib/webviewer',
14 rename: { stripBase: 4 },
15 },
16 ],
17 }),
18 ],
19});

Info

Your vite.config.js file may look slightly different depending on the framework you’re using. The key requirement is to add the viteStaticCopy plugin to the plugins array. Make sure to import the plugin correctly:

JavaScript

1import { viteStaticCopy } from 'vite-plugin-static-copy';
2

4. Create the PDF viewer

Next, instantiate the Apryse WebViewer SDK and mount it in your Vite project. This involves creating a container for the viewer and initializing WebViewer so it loads correctly at runtime.

  1. In Visual Studio Code, replace the contents of the src/App.jsx file with the following and save:

React (JSX)

src/App.jsx

1import { useEffect, useRef } from 'react';
2import * as WebViewerModule from '@pdftron/webviewer';
3
4/**
5 * Normalize WebViewer export to handle different module formats
6 * (ESM vs CommonJS, default vs named exports)
7 */
8function normalizeWebViewer(mod) {
9 if (typeof mod === 'function') return mod;
10 if (typeof mod?.default === 'function') return mod.default;
11 if (typeof mod?.WebViewer === 'function') return mod.WebViewer;
12 if (typeof mod?.default?.WebViewer === 'function') return mod.default.WebViewer;
13 if (typeof mod?.default?.default === 'function') return mod.default.default;
14 throw new Error('WebViewer function not found in module');
15}
16
17// Extract correct WebViewer constructor function
18const WebViewer = normalizeWebViewer(WebViewerModule);
19
20function App() {
21 // Create reference to DOM element where WebViewer will mount
22 const viewerRef = useRef(null);
23
24 useEffect(() => {
25 // Initialize WebViewer once when component mounts
26 WebViewer(
27 {
28 // Path to copied WebViewer static assets
29 path: 'lib/webviewer',
30 // Replace with your Apryse license key
31 licenseKey: 'YOUR_LICENSE_KEY',
32 // Initial document to load when WebViewer starts (optional)
33 initialDoc: 'https://pdftron.s3.amazonaws.com/downloads/pl/demo-annotated.pdf',
34 },
35 // Attach WebViewer to container element
36 viewerRef.current
37 ).then((instance) => {
38 // Access WebViewer instance here if needed
39 // const { UI, Core } = instance;
40 });
41 // Empty dependency array ensures this runs only once
42 }, []);
43 return (
44 // Container element for WebViewer
45 <div
46 ref={viewerRef}
47 style={{ height: '100vh', width: '100%', margin: '0 auto' }}
48 />
49 );
50}
51
52export default App;

Info

If you're signed in with an Apryse account, your license key is automatically prepopulated in all code snippets.

2. Replace the contents of the src/main.jsx file with the following and save:

React (JSX)

src/main.jsx

1import { StrictMode } from 'react';
2import { createRoot } from 'react-dom/client';
3
4import App from './App.jsx';
5
6createRoot(document.getElementById('root')).render(
7 <App />
8);

Info

In React 18 and later, useEffect may run twice in development when Strict Mode is enabled (which Vite uses by default). This can cause WebViewer to initialize twice and to display a duplicate instance. This behavior is expected and doesn't affect production builds.

For this example, you can avoid duplicate initialization by removing the StrictMode wrapper in src/main.jsx. However, note that Strict Mode helps identify issues like memory leaks, so removing it isn't recommended for production or more complex applications.

5. Verify your output

You can now load and display a PDF document in the WebViewer UI. Run your React application to launch WebViewer and see the PDF in your browser.

  1. From your project directory, run the following command to start the application:

Shell

1npm run dev

A successful output looks similar to:

Shell

1> webviewer-vite@0.0.0 dev
2> vite
3
4
5 VITE v8.0.16 ready in 920 ms
6
7 ➜ Local: http://localhost:5173/
8 ➜ Network: use --host to expose
9 ➜ press h + enter to show help
10[vite-plugin-static-copy] Collected 817 items.

2. Open the localhost URL from your terminal to view the WebViewer UI and PDF document.

Clean up CSS

If you created your project using Vite’s scaffolding tool, the default CSS files included with the template can interfere with WebViewer’s layout. If the viewer doesn't appear or renders incorrectly, remove or clear the styles from any default CSS files (such as style.css or index.css).

Get started video

In this 4-minute video, learn the fundamentals of Apryse WebViewer, including key concepts for installation and initialization in any web application.

Overview of Apryse WebViewer fundamentals, including installation and initialization.

Next steps

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales