react-pdf

repository·main·Indexed 11 days ago

https://github.com/wojtekmaj/react-pdf

A React library for displaying existing PDF files within applications. It provides core components including Document for loading and managing files, Page for rendering individual pages with support for canvas, text, and annotation layers, and Outline for displaying tables of contents. The library integrates with PDF.js and offers hooks like useDocumentContext, useOutlineContext, and usePageContext for state management.

Tokens
4.7K
Snippets
16
Records
21
Agent score
93%

What's inside react-pdf

  1. Access Page render properties via children

    main

    The Page component supports a render prop pattern via its children prop. This allows you to access the internal state of the page (like the page object, scale, rotate, and pageNumber) within your own custom components.

    When using a function as a child, the function receives a PageRenderProps object.

    <Page pageNumber={1}>
      {(props) => (
        <div>
          Current scale: {props.scale}
          Current rotation: {props.rotate}
        </div>
      )}
    </Page>
  2. Handle Thumbnail click navigation

    main

    When a user clicks a Thumbnail, the component needs a way to navigate to that page. You must ensure one of the following is available:

    1. onItemClick: Provide a custom callback function. This is the preferred way to handle navigation manually (e.g., updating your own application state or scrolling a container).
    2. linkService: If onItemClick is not provided, the component looks for a linkService in the document context. If a linkService is present, it will call linkService.goToPage(pageNumber) automatically.

    If neither a custom onItemClick nor a linkService is available, the click will fail to perform navigation.

    <Thumbnail 
      pageNumber={2} 
      onItemClick={({ pageNumber }) => {
        console.log('Navigating to page:', pageNumber);
        // Implement your navigation logic here
      }} 
    />
  3. Use the Outline component to display a table of contents

    main

    The <Outline /> component renders the PDF document's outline (table of contents).

    There are two ways to use it:

    1. Inside <Document />: Place <Outline /> as a child of <Document />. It will automatically use the document context.
    2. Standalone: Pass an explicit pdf prop to <Outline />. This pdf object (a PDFDocumentProxy) can be obtained from the onLoadSuccess callback of a <Document /> component.

    If no document is provided via context or the pdf prop, the component will throw an error.

    // Option 1: Inside Document
    <Document file="example.pdf">
      <Outline />
    </Document>
    
    // Option 2: Standalone with explicit pdf prop
    const [pdf, setPdf] = useState<PDFDocumentProxy | null>(null);
    
    return (
      <>
        <Document file="example.pdf" onLoadSuccess={({ pdf }) => setPdf(pdf)} />
        {pdf && <Outline pdf={pdf} />}
      </>
    );
  4. Configure the PDF.js worker

    main

    To ensure react-pdf functions correctly, you must configure the PDF.js worker. The library exports the underlying pdfjs object, which allows you to set the GlobalWorkerOptions.workerSrc.

    By default, the entrypoint attempts to set the worker source to 'pdf.worker.mjs'. You may need to adjust this path depending on your bundler configuration (e.g., Webpack, Vite) to point to the actual location of the worker file.

    import { pdfjs } from 'react-pdf';
    
    pdfjs.GlobalWorkerOptions.workerSrc = 'path/to/your/pdf.worker.mjs';
  5. Use the Document component to render PDFs

    main

    The Document component is the primary entry point for rendering PDF files in react-pdf. It handles loading the file, managing the PDF.js lifecycle, and providing context to child components.

    Key Usage Patterns

    1. Basic Rendering

    Pass a file prop (URL, file object, or parameter object) and use the render prop pattern to access the pdf object for rendering pages.

    <Document 
      file="https://example.com/sample.pdf"
      onLoadSuccess={({ pdf }) => console.log(`Loaded ${pdf.numPages} pages`)}
    >
      {({ pdf }) => (
        <div>
          {/* Render pages here using the pdf object */}
        </div>
      )}
    </Document>

    2. Handling Loading, Error, and No Data States

    You can customize the UI for different lifecycle states using loading, error, and noData props.

    <Document
      file={myFile}
      loading={<p>Please wait...</p>}
      error={<p>Failed to load PDF.</p>}
      noData={<p>No file selected.</p>}
    />

    3. Managing Password Protected PDFs

    Use the onPassword callback to handle password prompts.

    <Document
      file={protectedFile}
      onPassword={(callback, reason) => {
        const password = prompt('Enter password:');
        callback(password);
      }}
    />

    Important Performance Note

    Because Document uses strict equality (===) to detect changes in the file and options props, you must memoize these values (e.g., using useMemo or component state) to prevent unnecessary reloads and performance warnings.

    // DO THIS
    const file = useMemo(() => ({ url: '...' }), []);
    const options = useMemo(() => ({ cMapUrl: '...' }), []);
    
    <Document file={file} options={options} />
  6. Customize text rendering with CustomTextRenderer

    main

    You can provide a CustomTextRenderer via the PageContextType to control how text items are converted into strings. This is useful for specialized text processing or formatting. The renderer receives the TextItem properties along with the current pageIndex, pageNumber, and itemIndex.

    export type CustomTextRenderer = (
      props: { pageIndex: number; pageNumber: number; itemIndex: number } & TextItem,
    ) => string;
  7. Use the Page component to render PDF pages

    main

    The Page component is used to display individual pages of a PDF. It should ideally be placed inside a <Document /> component. If you don't use <Document />, you must pass an explicit pdf prop (the PDFDocumentProxy obtained from a document's onLoadSuccess callback).

    Key features include:

    • Scaling and Sizing: Control dimensions via scale, width, or height. If both width and height are provided, height is ignored. If width and scale are provided, the width is multiplied by the scale.
    • Layers: Supports rendering a Canvas (main layer), a TextLayer (for text selection), and an AnnotationLayer (for links/forms).
    • Custom Rendering: Set renderMode="custom" and provide a customRenderer to take full control of the rendering process.
    • State Callbacks: Provides hooks for loading, rendering, and error states.
    <Page 
      pdf={pdf} 
      pageNumber={1} 
      scale={1.5} 
      renderTextLayer={true} 
      renderAnnotationLayer={true} 
    />
  8. Configure ThumbnailProps

    main

    The Thumbnail component accepts ThumbnailProps, which is a subset of PageProps with specific overrides and additional properties for interaction.

    Additional Props

    • className (type: ClassName): Class name(s) added to the rendered element alongside the default react-pdf__Thumbnail. Can be a string or an array of strings.
    • onItemClick (type: (args: OnItemClickArgs) => void): A callback function triggered when the thumbnail is clicked. Use this to implement custom navigation logic.
      • Args: { dest, pageIndex, pageNumber }

    Excluded PageProps

    The following PageProps are omitted/ignored by Thumbnail to ensure it behaves as a lightweight preview:

    • className (overridden by ThumbnailProps.className)
    • customTextRenderer
    • onGetAnnotationsError / onGetAnnotationsSuccess
    • onGetTextError / onGetTextSuccess
    • onRenderAnnotationLayerError / onRenderAnnotationLayerSuccess
    • onRenderTextLayerError / onRenderTextLayerSuccess
    • renderAnnotationLayer (always false)
    • renderForms
    • renderTextLayer (always false)
  9. Filter annotations with FilterAnnotations

    main

    The FilterAnnotations function allows you to intercept and modify the list of annotations on a page. It receives FilterAnnotationsArgs (containing the original annotations) and must return a modified Annotations array.

    export type FilterAnnotationsArgs = {
      annotations: Annotations;
    };
    
    export type FilterAnnotations = (args: FilterAnnotationsArgs) => Annotations;
  10. Access Document internals via ref

    main

    You can attach a ref to the Document component to access its internal services and page references. The ref provides an object with the following properties:

    • linkService: A React.RefObject<LinkService> used for managing internal links and annotations.
    • pages: A React.RefObject<HTMLDivElement[]> containing references to the rendered page elements.
    • viewer: A React.RefObject<{ scrollPageIntoView: (args: ScrollPageIntoViewArgs) => void }> which provides a method to programmatically scroll to specific pages or destinations.
  11. Use the react-pdf core components

    main

    The react-pdf package provides several primary components for rendering PDF content in a React application:

    • Document: The top-level component used to load and manage a PDF file.
    • Page: Renders a specific page from a loaded Document.
    • Outline: Renders the document outline (table of contents).
    • Thumbnail: Renders a small thumbnail representation of a page.
    • PasswordResponses: A component used to handle password-protected PDF files by providing a way to capture user input.
    import { Document, Page, Outline, Thumbnail } from 'react-pdf';
  12. Handle PDF document and page lifecycle events

    main

    The library provides several callback types to handle the lifecycle of documents and pages.

    Document Events:

    • OnDocumentLoadSuccess: Triggered when the PDFDocumentProxy is ready.
    • OnDocumentLoadProgress: Provides loaded and total bytes.
    • OnDocumentLoadError: Triggered on loading failure.

    Page Events:

    • OnPageLoadSuccess: Triggered when a PageCallback (proxy + dimensions) is ready.
    • OnRenderSuccess: Triggered when the page has finished rendering.
    • OnRenderError: Triggered if rendering fails.
    export type OnDocumentLoadSuccess = (document: DocumentCallback) => void;
    export type OnPageLoadSuccess = (page: PageCallback) => void;
    export type OnRenderSuccess = (page: PageCallback) => void;
    export type OnRenderError = (error: Error) => void;