Skip to content

Recipes

Wojciech Maj edited this page May 15, 2020 · 15 revisions

Display single page

import React from 'react';
import { Document, Page } from 'react-pdf';

import samplePDF from './test.pdf';

export default function Test() {
  return (
    <Document file={samplePDF}>
      <Page pageNumber={1} />
    </Document>
  );
}

Display all pages

Please note that this approach may cause performance issues.

import React, { useState } from 'react';
import { Document, Page } from 'react-pdf';

import samplePDF from './test.pdf';

export default function Test() {
  const [numPages, setNumPages] = useState(null);

  function onDocumentLoadSuccess({ numPages }) {
    setNumPages(numPages);
  }

  return (
    <Document
      file={samplePDF}
      onLoadSuccess={onDocumentLoadSuccess}
    >
      {Array.from(
        new Array(numPages),
        (el, index) => (
          <Page
            key={`page_${index + 1}`}
            pageNumber={index + 1}
          />
        ),
      )}
    </Document>
  );
}

Display single page with navigation

import React, { useState } from 'react';
import { Document, Page } from 'react-pdf';

import samplePDF from './test.pdf';

export default function Test() {
  const [numPages, setNumPages] = useState(null);
  const [pageNumber, setPageNumber] = useState(1);

  function onDocumentLoadSuccess({ numPages }) {
    setNumPages(numPages);
    setPageNumber(1);
  }

  function changePage(offset) {
    setPageNumber(prevPageNumber => prevPageNumber + offset);
  }

  function previousPage() {
    changePage(-1);
  }

  function nextPage() {
    changePage(1);
  }

  return (
    <>
      <Document
        file={samplePDF}
        onLoadSuccess={onDocumentLoadSuccess}
      >
        <Page pageNumber={pageNumber} />
      </Document>
      <div>
        <p>
          Page {pageNumber || (numPages ? 1 : '--')} of {numPages || '--'}
        </p>
        <button
          type="button"
          disabled={pageNumber <= 1}
          onClick={previousPage}
        >
          Previous
        </button>
        <button
          type="button"
          disabled={pageNumber >= numPages}
          onClick={nextPage}
        >
          Next
        </button>
      </div>
    </>
  );
}

Highlight text on the page

import React, { useState } from 'react';
import { Document, Page } from 'react-pdf';

import samplePDF from './test.pdf';

// https://gist.github.com/wojtekmaj/f265f55e89ccb4ce70fbd2f8c7b1d95d
function highlightPattern(text, pattern) {
  const splitText = text.split(pattern);

  if (splitText.length <= 1) {
    return text;
  }

  const matches = text.match(pattern);

  return splitText.reduce((arr, element, index) => (matches[index] ? [
    ...arr,
    element,
    <mark key={index}>
      {matches[index]}
    </mark>,
  ] : [...arr, element]), []);
}

export default function Test() {
  const [searchText, setSearchText] = useState('');

  function makeTextRenderer(searchText) {
    return function textRenderer(textItem) {
      return highlightPattern(textItem.str, searchText);
    }
  }

  function onChange(event) {
    setSearchText(event.target.value);
  }

  return (
    <>
      <Document
        file={samplePDF}
        onLoadSuccess={onDocumentLoadSuccess}
      >
        <Page
          pageNumber={1}
          customTextRenderer={makeTextRenderer(searchText)}
        />
      </Document>
      <div>
        <label htmlFor="search">Search:</label>
        <input type="search" id="search" value={searchText} onChange={onChange} />
      </div>
    </>
  );
}

Display interactive Table of Contents

Note that this example is nearly identical to the next one. onItemClick can be both used in Document and Outline components.

import React, { useState } from 'react';
import { Document, Outline, Page } from 'react-pdf';

import samplePDF from './test.pdf';

export default function Test() {
  const [pageNumber, setPageNumber] = useState(1);

  function onItemClick({ pageNumber: itemPageNumber }) {
    setPageNumber(itemPageNumber);
  }

  return (
    <Document file={samplePDF}>
      <Outline onItemClick={onItemClick} />
      <Page
        pageNumber={pageNumber || 1}
      />
    </Document>
  );
}

Handle external links

Note that this example is nearly identical to the previous one. onItemClick can be both used in Document and Outline components.

import React, { useState } from 'react';
import { Document, Outline, Page } from 'react-pdf';

import samplePDF from './test.pdf';

export default function Test() {
  const [pageNumber, setPageNumber] = useState(1);

  function onItemClick({ pageNumber: itemPageNumber }) {
    setPageNumber(itemPageNumber);
  }

  return (
    <Document
      file={samplePDF}
      onItemClick={onItemClick}
    >
      <Page
        pageNumber={pageNumber || 1}
      />
    </Document>
  );
}