Migrating from Nutrient Web SDK to React PDF Viewer
24 Jul 20268 minutes to read
This guide helps you migrate applications built using Nutrient Web SDK (formerly PSPDFKit Web SDK) to the React PDF Viewer. It outlines architectural differences, feature mapping, and required changes in a React-based application.
Overview
Nutrient Web SDK (PSPDFKit) provides a powerful Web SDK for PDF viewing and editing, typically integrated via an SDK initialization model.
React PDF Viewer offers a declarative React component with built-in UI, annotations, form handling, and optimized performance, without requiring external runtime dependencies or cloud services.
Architecture notes
This guide focuses on replacing a Nutrient/PSPDFKit SDK integration with a React PDF Viewer component. Important migration considerations include the integration pattern (imperative SDK mounts vs. declarative React component), how UI/tooling is provided (SDK-provided UI vs. injected services), and how annotations and form workflows are persisted and handled. The step-by-step instructions below are designed to help migrate code, event handlers, and persistence workflows to the PdfViewerComponent.
Installation
Nutrient Web SDK (PSPDFKit / Nutrient)
The Nutrient Web SDK can be used via CDN or installed as a package. The CDN exposes window.NutrientViewer and is a quick way to try the SDK; for production you may prefer the package manager installation.
# CDN: add the script tag to `index.html` (example version shown)
<!-- <script src="https://cdn.cloud.nutrient.io/[email protected]/nutrient-viewer.js"></script> -->
# or install the package for local use
npm install @nutrient-sdk/viewerReact PDF Viewer
npm install @syncfusion/ej2-react-pdfviewerViewer initialization comparison
Nutrient Web SDK (CDN example)
import { useEffect, useRef } from 'react';
function App() {
const containerRef = useRef(null);
useEffect(() => {
const container = containerRef.current;
const { NutrientViewer } = window;
if (container && NutrientViewer) {
NutrientViewer.load({
container,
// document can be a URL or a file in `public/`
document: 'https://www.nutrient.io/downloads/nutrient-web-demo.pdf',
});
}
return () => {
NutrientViewer?.unload(container);
};
}, []);
return (
// Ensure explicit width/height on the container
<div ref={containerRef} style={{ height: '100vh', width: '100vw' }} />
);
}
export default App;React PDF Viewer
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import {
PdfViewerComponent,
Toolbar,
Magnification,
Navigation,
Annotation,
TextSearch,
FormFields,
Inject,
} from '@syncfusion/ej2-react-pdfviewer';
export function App() {
return (
<PdfViewerComponent
id="container"
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
resourceUrl="https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib"
style={{ height: '640px' }}
>
<Inject
services={[
Toolbar,
Magnification,
Navigation,
Annotation,
TextSearch,
FormFields,
]}
/>
</PdfViewerComponent>
);
}
const root = ReactDOM.createRoot(document.getElementById('sample'));
root.render(<App />);Feature checklist (Syncfusion)
Event Handling
Nutrient Web SDK
Check Events Guide to know more about event handling in Nutrient Web SDK.
instance.addEventListener('documentLoaded', () => {
console.log('Document loaded');
});Syncfusion Viewer
Check Syncfusion Events Guide to know more about event handling in React PDF Viewer.
<PdfViewerComponent
documentLoad={() => console.log('Document loaded')}
pageChange={(args) => console.log(args.currentPage)}
/>Migration Checklist
- Remove PSPDFKit SDK initialization logic
- Replace DOM-based SDK mounting with PdfViewerComponent
- Map annotation and form workflows to injected services
- Verify feature parity and licensing requirements
How-to: minimal migration steps
Follow these concise steps to migrate a Nutrient integration to PdfViewerComponent.
- Ensure the Nutrient container has explicit dimensions before replacing it.
- Replace the
NutrientViewer.load()mount with a ReactPdfViewerComponentas shown below.
Minimal file difference (before → after)
Before (e.g., src/viewers/NutrientViewer.js):
// CDN usage or package: mounting into a DOM node
import { useEffect, useRef } from 'react';
function OldViewer() {
const containerRef = useRef(null);
useEffect(() => {
const container = containerRef.current;
const { NutrientViewer } = window;
NutrientViewer?.load({ container, document: '/sample.pdf' });
return () => NutrientViewer?.unload(container);
}, []);
return <div ref={containerRef} style= />;
}After (e.g., src/components/PdfViewer.js):
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import {
PdfViewerComponent,
Toolbar,
Magnification,
Navigation,
Annotation,
TextSearch,
FormFields,
Inject,
} from '@syncfusion/ej2-react-pdfviewer';
export function App() {
return (
<PdfViewerComponent
id="container"
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
resourceUrl="https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib"
style={{ height: '640px' }}
>
<Inject
services={[
Toolbar,
Magnification,
Navigation,
Annotation,
TextSearch,
FormFields,
]}
/>
</PdfViewerComponent>
);
}
const root = ReactDOM.createRoot(document.getElementById('sample'));
root.render(<App />);API mapping: Nutrient → Syncfusion
| Nutrient Web SDK | React PDF Viewer |
|---|---|
NutrientViewer.load({ container, document }) |
Use <PdfViewerComponent documentPath="..." /> or load() for programmatic loads. |
NutrientViewer.unload(container) |
unload() / component unmount; call viewerRef.current.unload() if using ref API. |
| Viewer-level events (document loaded, page change) |
documentLoad, pageChange, pageRenderComplete events on PdfViewerComponent. |
| Annotations API (add/serialize) |
addAnnotation(), importAnnotation(), exportAnnotation(), exportAnnotationsAsBase64String(). |
| Search API | Enable enableTextSearch or use extractText() for programmatic extraction. |
Reference: key Syncfusion PdfViewerComponent methods & events
- PdfViewerComponent API index
- load() — programmatically load a PDF.
- download() — trigger download of current document.
- addAnnotation(annotation: any) — add an annotation programmatically.
- exportAnnotation(annotationDataFormat) / exportAnnotationsAsBase64String() — export annotations for persistence.
- extractText(pageIndex: number, options?: any): — extract text and coordinates.
- Events: documentLoad, pageRenderComplete, pageChange, annotationAdd, annotationRemove, toolbarClick.