Display PDFs in your React app as easily as if they were images.
npx @tessl/cli install tessl/npm-react-pdf@10.1.0React-PDF is a React component library for displaying PDF documents in React applications with the same ease as displaying images. It provides a comprehensive set of components including Document, Page, Outline, and Thumbnail that leverage PDF.js for robust PDF rendering capabilities.
npm install react-pdfimport { Document, Page, Outline, Thumbnail, pdfjs } from "react-pdf";For CommonJS:
const { Document, Page, Outline, Thumbnail, pdfjs } = require("react-pdf");import { Document, Page, pdfjs } from "react-pdf";
// Configure PDF.js worker (required)
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs',
import.meta.url,
).toString();
function MyPDFViewer() {
const [numPages, setNumPages] = useState(null);
const [pageNumber, setPageNumber] = useState(1);
function onDocumentLoadSuccess({ numPages }) {
setNumPages(numPages);
}
return (
<div>
<Document
file="https://example.com/sample.pdf"
onLoadSuccess={onDocumentLoadSuccess}
>
<Page pageNumber={pageNumber} />
</Document>
<p>
Page {pageNumber} of {numPages}
</p>
</div>
);
}React-PDF is built around several key components:
Direct integration with Mozilla's PDF.js library for PDF processing, worker configuration, and advanced PDF operations.
import { pdfjs } from "react-pdf";
// PDF.js library object for worker configuration and advanced operations
const pdfjs: typeof import('pdfjs-dist');
interface GlobalWorkerOptions {
workerSrc: string;
}
// Configure PDF.js worker (required for functionality)
pdfjs.GlobalWorkerOptions.workerSrc = string;
// Access to full PDF.js API for advanced operations
pdfjs.getDocument(src: DocumentInitParameters): PDFDocumentLoadingTask;Document loading and management functionality for handling PDF files from various sources with comprehensive loading states and error handling.
function Document(props: DocumentProps): React.ReactElement;
interface DocumentProps {
file?: File;
onLoadSuccess?: (document: PDFDocumentProxy) => void;
onLoadError?: (error: Error) => void;
onLoadProgress?: (args: { loaded: number; total: number }) => void;
onPassword?: (callback: (password: string | null) => void, reason: PasswordResponse) => void;
children?: React.ReactNode | ((props: DocumentRenderProps) => React.ReactNode);
}
type File = string | ArrayBuffer | Blob | Source | null;
interface Source {
data?: BinaryData;
url?: string;
range?: PDFDataRangeTransport;
}Page rendering system with multiple layer support and extensive customization options for displaying individual PDF pages.
function Page(props: PageProps): React.ReactElement;
interface PageProps {
pageNumber?: number;
pageIndex?: number;
scale?: number;
rotate?: number | null;
width?: number;
height?: number;
renderMode?: RenderMode;
renderTextLayer?: boolean;
renderAnnotationLayer?: boolean;
renderForms?: boolean;
onLoadSuccess?: (page: PageCallback) => void;
onLoadError?: (error: Error) => void;
}
type RenderMode = 'canvas' | 'custom' | 'none';
interface PageCallback extends PDFPageProxy {
width: number;
height: number;
originalWidth: number;
originalHeight: number;
}Navigation components for PDF outline (table of contents) and thumbnail displays to enhance user experience.
function Outline(props: OutlineProps): React.ReactElement | null;
function Thumbnail(props: ThumbnailProps): React.ReactElement;
interface OutlineProps {
onItemClick?: (args: OnItemClickArgs) => void;
onLoadSuccess?: (outline: PDFOutline) => void;
onLoadError?: (error: Error) => void;
}
interface OnItemClickArgs {
dest?: Dest;
pageIndex: number;
pageNumber: number;
}React hooks for accessing PDF context data and state within component trees.
function useDocumentContext(): DocumentContextType;
function usePageContext(): PageContextType;
function useOutlineContext(): OutlineContextType;
interface DocumentContextType {
imageResourcesPath?: ImageResourcesPath;
linkService: LinkService;
onItemClick?: (args: OnItemClickArgs) => void;
pdf?: PDFDocumentProxy | false;
registerPage: RegisterPage;
renderMode?: RenderMode;
rotate?: number | null;
unregisterPage: UnregisterPage;
}
interface PageContextType {
_className?: string;
canvasBackground?: string;
customTextRenderer?: CustomTextRenderer;
devicePixelRatio?: number;
onGetAnnotationsError?: OnGetAnnotationsError;
onGetAnnotationsSuccess?: OnGetAnnotationsSuccess;
onGetStructTreeError?: OnGetStructTreeError;
onGetStructTreeSuccess?: OnGetStructTreeSuccess;
onGetTextError?: OnGetTextError;
onGetTextSuccess?: OnGetTextSuccess;
onRenderAnnotationLayerError?: OnRenderAnnotationLayerError;
onRenderAnnotationLayerSuccess?: OnRenderAnnotationLayerSuccess;
onRenderError?: OnRenderError;
onRenderSuccess?: OnRenderSuccess;
onRenderTextLayerError?: OnRenderTextLayerError;
onRenderTextLayerSuccess?: OnRenderTextLayerSuccess;
page: PDFPageProxy | false | undefined;
pageIndex: number;
pageNumber: number;
renderForms: boolean;
renderTextLayer: boolean;
rotate: number;
scale: number;
}
interface OutlineContextType {
onItemClick?: (args: OnItemClickArgs) => void;
}interface PDFDocumentProxy {
numPages: number;
getPage(pageNumber: number): Promise<PDFPageProxy>;
getOutline(): Promise<PDFOutline | null>;
}
interface PDFPageProxy {
pageNumber: number;
rotate: number;
getViewport(params: { scale: number; rotation?: number }): PageViewport;
render(params: RenderParameters): RenderTask;
getTextContent(): Promise<TextContent>;
getAnnotations(): Promise<Annotations>;
}
interface PageViewport {
width: number;
height: number;
transform: number[];
}
type ClassName = string | null | undefined | (string | null | undefined)[];
type NodeOrRenderer = React.ReactNode | (() => React.ReactNode);
type RegisterPage = (pageIndex: number, ref: HTMLDivElement) => void;
type UnregisterPage = (pageIndex: number) => void;
type Annotations = any[]; // PDF.js annotation types
type CustomTextRenderer = (
props: { pageIndex: number; pageNumber: number; itemIndex: number } & TextItem,
) => string;
interface Options extends Omit<DocumentInitParameters, 'url' | 'data' | 'range'> {
cMapUrl?: string;
httpHeaders?: Record<string, string>;
wasmUrl?: string;
withCredentials?: boolean;
}
// LinkService class for handling PDF links and navigation
class LinkService {
externalLinkEnabled: boolean;
externalLinkRel?: ExternalLinkRel;
externalLinkTarget?: ExternalLinkTarget;
isInPresentationMode: boolean;
pdfDocument?: PDFDocumentProxy | null;
pdfViewer?: any | null;
constructor();
setDocument(pdfDocument: PDFDocumentProxy | null): void;
setViewer(pdfViewer: any): void;
getDestinationHash(dest: string | any[]): string;
getAnchorUrl(hash: string): string;
setHash(hash: string): void;
executeNamedAction(action: string): void;
onFileAttachmentAnnotation(): void;
cachePageRef(pageNum: number, pageRef: any): void;
isPageVisible(pageNumber: number): boolean;
isPageCached(pageNumber: number): boolean;
}type OnDocumentLoadSuccess = (document: PDFDocumentProxy) => void;
type OnDocumentLoadError = (error: Error) => void;
type OnDocumentLoadProgress = (args: { loaded: number; total: number }) => void;
type OnPageLoadSuccess = (page: PageCallback) => void;
type OnPageLoadError = (error: Error) => void;
type OnPasswordCallback = (password: string | null) => void;
type OnGetAnnotationsError = (error: Error) => void;
type OnGetAnnotationsSuccess = (annotations: Annotations) => void;
type OnGetStructTreeError = (error: Error) => void;
type OnGetStructTreeSuccess = (tree: StructTreeNode) => void;
type OnGetTextError = (error: Error) => void;
type OnGetTextSuccess = (textContent: TextContent) => void;
type OnRenderAnnotationLayerError = (error: unknown) => void;
type OnRenderAnnotationLayerSuccess = () => void;
type OnRenderError = (error: Error) => void;
type OnRenderSuccess = (page: PageCallback) => void;
type OnRenderTextLayerError = (error: Error) => void;
type OnRenderTextLayerSuccess = () => void;
// PasswordResponses constant object
const PasswordResponses = {
NEED_PASSWORD: 1,
INCORRECT_PASSWORD: 2,
} as const;
type PasswordResponse = (typeof PasswordResponses)[keyof typeof PasswordResponses];Types re-exported from PDF.js for text content, structure tree, and annotations.
interface TextContent {
items: (TextItem | TextMarkedContent)[];
styles: Record<string, TextStyle>;
}
interface TextItem {
str: string;
dir: string;
width: number;
height: number;
transform: number[];
fontName: string;
}
interface TextMarkedContent {
type: string;
}
interface StructTreeNode {
role?: string;
children?: StructTreeNode[];
alt?: string;
lang?: string;
}
interface TextStyle {
ascent: number;
descent: number;
vertical: boolean;
fontFamily: string;
fontSize: number;
}interface DocumentRenderProps {
pdf: PDFDocumentProxy;
linkService: LinkService;
registerPage: (pageIndex: number, ref: HTMLDivElement) => void;
unregisterPage: (pageIndex: number) => void;
}
interface PageRenderProps {
page: PDFPageProxy;
pageIndex: number;
pageNumber: number;
scale: number;
rotate: number;
}