React PDF viewer
v1.7.0

Updates

v1.7.0

New features

  • Add onPageChange callback that is invoked when user changes page:
import Viewer, { PageChangeEvent } from '@phuocng/react-pdf-viewer';

const handlePageChange = (e: PageChangeEvent) => {
    console.log(`Changed to page: ${e.currentPage}`)
};

<Viewer
    fileUrl='/path/to/document.pdf'
    onPageChange={handlePageChange}
/>
  • Add onCanvasLayerRender event that is invoked when the canvas layer is rendered completely.
import Viewer, { CanvasLayerRenderEvent } from '@phuocng/react-pdf-viewer';

const onCanvasLayerRender = (e: CanvasLayerRenderEvent) => {
    // `e.ele` is the canvas element
    const canvas = e.ele;
    // Do something with the canvas element
};

<Viewer
    fileUrl='/path/to/document.pdf'
    onCanvasLayerRender={onCanvasLayerRender}
/>
  • Add onTextLayerRender event that is invoked when the text layer is ready.
import Viewer, { TextLayerRenderEvent } from '@phuocng/react-pdf-viewer';

const onTextLayerRender = (e: TextLayerRenderEvent) => {
    // For example, we can find all text elements that look like a link, 
    // and replace it with `a` elements
};

<Viewer
    fileUrl='/path/to/document.pdf'
    onTextLayerRender={onTextLayerRender}
/>
  • Support non-latin characters via the characterMap option
import Viewer, { CharacterMap } from '@phuocng/react-pdf-viewer';

const characterMap: CharacterMap = {
    isCompressed: true,
    url: 'https://unpkg.com/pdfjs-dist@2.4.456/cmaps/',
};

<Viewer
    characterMap={characterMap}
    fileUrl='/path/to/document.pdf'
/>

Bug fixes

  • The viewer doesn't jump to the destination or searching result exactly

Breaking changes

The parameters of onDocumentLoad and onZoom are changed as following:

v1.6.0v1.7.0
onDocumentLoad(doc)onDocumentLoad({ doc })
onZoom(doc, scale)onZoom({ doc, scale })

v1.6.0

New features

  • The annotation layer is rewritten. Support the following type of annotations:

    • Caret
    • Circle
    • File attachment
    • Free text
    • Highlight
    • Ink
    • Line
    • Link
    • Polygon
    • Polyline
    • Popup
    • Square
    • Squiggly
    • Stamp
    • StrikeOut
    • Text
    • Underline
  • The link annotation supports named actions which allow to jump to the first, last, next or previous pages

  • Customize error renderer.
const renderError = (error: LoadError) => {
    let message = '';
    switch (error.name) {
        case 'InvalidPDFException':
            message = 'The document is invalid or corrupted';
            break;
        case 'MissingPDFException':
            message = 'The document is missing';
            break;
        case 'UnexpectedResponseException':
            message = 'Unexpected server response';
            break;
        default:
            message = 'Cannot load the document';
            break;
    }

    return (<div>{message}</div>);
};

<Viewer
    fileUrl={fileUrl}
    renderError={renderError}
/>

Improvements

  • Allow to control the fileUrl option
  • Bookmarks support external links
  • Support external links

Bug fixes

  • The canvas layer is blurry
  • The tooltip, popover positions are not correct in some cases
  • The drag zone isn't visible if the main area is scrolled
  • The document rotated initially isn't displayed properly

v1.5.0

New features

  • Highlight given keyword in the first render
<Viewer
    fileUrl='/path/to/document.pdf'
    // The `keyword` option can be a string or a regular expression
    // keyword='PDF Library'
    keyword={new RegExp('pdf document', 'i')}
/>
  • Add new SVG layer which can be used to replace the canvas layer
const renderPage = (props: RenderPageProps) => {
    return (
        <>
            {props.svgLayer.children}
            {props.textLayer.children}
            {props.annotationLayer.children}
        </>
    );
};

<Viewer
    fileUrl='/path/to/document.pdf'
    renderPage={renderPage}
/>
  • Customize page renderer. The following code adds a simple Draft watermark at the center of every page:
const renderPage: RenderPage = (props: RenderPageProps) => (
    <>
        {props.canvasLayer.children}
        <div
            style={{
                alignItems: 'center',
                display: 'flex',
                height: '100%',
                justifyContent: 'center',
                left: 0,
                position: 'absolute',
                top: 0,
                width: '100%',
            }
        }>
            <div
                style={{
                    color: 'rgba(0, 0, 0, 0.2)',
                    fontSize: `${8 * props.scale}rem`,
                    fontWeight: 'bold',
                    textTransform: 'uppercase',
                    transform: 'rotate(-45deg)',
                    userSelect: 'none',
                }}
            >
                Draft
            </div>
        </div>
        {props.annotationLayer.children}
        {props.textLayer.children}
    </>
);

<Viewer
    fileUrl='/path/to/document.pdf'
    renderPage={renderPage}
/>

Improvements

  • The default scale can be a special zoom level. For example, we can fit page in the container initially:
<Viewer
    fileUrl='/path/to/document.pdf'
    defaultScale={SpecialZoomLevel.PageFit}
/>
  • The fileUrl option can be Uint8Array:
<Viewer
    fileUrl={new Uint8Array([...])}
/>
  • Add styles for error message

v1.4.0

New features

  • Add new optional parameter indicating the page that will be displayed initially
<Viewer
    // The page is zero-based index
    // We will display the third page initially
    initialPage={2}
/>
  • Add new optional parameter to define the prefix of CSS classes
<Viewer
    prefixClass='viewer'
/>
  • Add new render parameter that includes many functions that could be called from outside of the component:
import Viewer, { RenderViewerProps, ScrollMode, SpecialZoomLevel, SelectionMode } from '@phuocng/react-pdf-viewer';

const render = (props: RenderViewerProps) => {
    return (
        <div>
            <div style={{ height: '500px' }}>
                {props.viewer}
            </div>
            <button onClick={() => props.jumpToPage(props.doc.numPages - 1)}>Jump to last page</button>
            <button onClick={() => props.rotate(90)}>Rotate +90 degrees</button>
            <button onClick={() => props.zoom(0.5)}>Zoom to 50%</button>
            <button onClick={() => props.zoom(SpecialZoomLevel.ActualSize)}>Zoom to actual size</button>
            <button onClick={() => props.changeScrollMode(ScrollMode.Wrapped)}>Switch to wrapped scrolling</button>
            <button onClick={() => props.changeSelectionMode(SelectionMode.Hand)}>Switch to hand tool</button>
            <button onClick={() => props.print()}>Print</button>
            <button onClick={() => props.download()}>Download</button>
        </div>
    );
};

<Viewer
    fileUrl={fileUrl}
    render={render}
/>

Improvement

  • All styles are moved to external CSS files. It's possible for us to override components' styles.

Bug fixes

  • Can't scroll and print on IE 11
  • Printing doesn't look good if the page size isn't set

v1.3.0

New features Expose all the buttons from the more actions popover to the toolbar. ToolbarSlot now includes

  • goToFirstPageButton: the button to go to the first page
  • goToLastPageButton: go to the last page
  • rotateClockwiseButton: rotate the document
  • rotateCounterclockwiseButton: rotate counterclockwise the document
  • textSelectionButton: switch to the text selection mode
  • handToolButton: switch to the hand tool mode
  • verticalScrollingButton: scroll the document vertically
  • horizontalScrollingButton: scroll the document horizontally
  • wrappedScrollingButton: display pages as a grid
  • documentPropertiesButton: show the document properties

v1.2.1

Improvements

  • Make the spinner thiner
  • Add minified CSS files

Bug fixes

  • Tooltip for the left/right buttons don't look good in full width mode
  • The view now takes full height by default. It fixes the issue that users can't navigate between pages from the toolbar in some cases

v1.2.0

New features

  • Provide the ability of printing document
  • Add new selectionMode option indicates the selection mode:
import Viewer, { SelectionMode } from '@phuocng/react-pdf-viewer';

<Viewer
    fileUrl="..." 
    // By default, it will be SelectionMode.Text
    selectionMode={SelectionMode.Hand}
/>
  • Add onDocumentLoad callback that uis invoked when the document is loaded completely
import Viewer, { PdfJs } from '@phuocng/react-pdf-viewer';

const documentLoad = (doc: PdfJs.PdfDocument) => {
    console.log(`Document is loaded: ${doc.numPages}`)
};

<Viewer
    fileUrl="..."
    onDocumentLoad={documentLoad}
/>
  • Add onZoom callback that is invoked when zooming in/out the document
import Viewer, { PdfJs } from '@phuocng/react-pdf-viewer';

const zoom = (doc: PdfJs.PdfDocument, scale: number) => {
    console.log(`Zoom document to ${scale}`);
};

<Viewer
    fileUrl="/path/to/document.pdf"
    onZoom={zoom}
/>

v1.1.0

New features

  • Add new, optional defaultScale parameter that indicates the default zoom level:
<Viewer defaultScale={1.5} ... />

Improvement

  • The document should fit best in the container initially

v1.0.1

Improvement

  • Support SSR

Bug fixes

  • Cannot re-export a type when --isolatedModules is set to true
  • The CSS files are missing in es6 package

v1.0.0

New features

  • Support password protected file
  • Can open a local file or remote file which is passed by given URL
  • User can drag and drop a file to open it
  • Support full screen
  • The text are selectable
  • User can search for given keyword
  • Rotate page in clockwise or counterclockwise
  • Different scrolling modes: vertical, horizontal, wrapping
  • Support text selection and hand mode
  • Display the list of attachments in sidebar

Navigation

  • Navigate between pages
  • Nagivate to the first and last page quickly
  • Display the thumbnails of pages in sidebar
  • Display the table of contents in sidebar
  • User can go to given section by following an item from the table of content
  • When user click on a link, it will be opened in the browser

Zooming

  • Zoom in and zoom out
  • Support special zoom level such as actual size, page fit, and page width

Localization

  • Support localization
  • Provide built-in English locale

Customization

  • Can customize the toolbar
  • Can customize the layout