Example: Disable text selection

This post will introduce two ways to prevent user from selecting the text in any page. Both of them need to change the way each page is rendered.

Use the user-select style

By default, each page is constructed by canvas, text, and annotation layers. In order to disable the text selection, we can wrap the text layer in a layer that uses the CSS property user-select: none:

import { Viewer, RenderPageProps } from '@react-pdf-viewer/core';

const renderPage = (props: RenderPageProps) => {
    return (
        <>
            {props.canvasLayer.children}
            <div style={{ userSelect: 'none' }}>
                {props.textLayer.children}
            </div>
            {props.annotationLayer.children}
        </>
    );
};

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

It's worth noting that even the text selection is disabled, user can still copy the text by

  • downloading the entire document from the toolbar
  • or inspecting the text and copying them via the browser's Developer Tools

(The sample code)

Remove the text layer

The approach above uses a CSS property to prevent users from selecting text. But the text are still there.

You can take it further by removing the text layer completely. The renderPage function now doesn't include the text layer anymore:

import { Viewer, RenderPageProps } from '@react-pdf-viewer/core';

const renderPage = (props: RenderPageProps) => {
    return (
        <>
            {props.canvasLayer.children}
            {props.annotationLayer.children}
        </>
    );
};

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

The search functionality will not work because it isn't possible to look for text in all pages. So, we have to remove the search and download buttons from the toolbar.

You should take a look at the toolbar plugin to see how we can customize the toolbar.

<Toolbar>
{
    (props: ToolbarSlot) => {
        const {
            CurrentPageInput, EnterFullScreen, GoToNextPage, GoToPreviousPage,
            NumberOfPages, Print, Zoom, ZoomIn,
            ZoomOut,
        } = props;
        return (
            <>
                <div style={{ padding: '0px 2px' }}>
                    <ZoomOut />
                </div>
                <div style={{ padding: '0px 2px' }}>
                    <Zoom />
                </div>
                <div style={{ padding: '0px 2px' }}>
                    <ZoomIn />
                </div>
                <div style={{ padding: '0px 2px', marginLeft: 'auto' }}>
                    <GoToPreviousPage />
                </div>
                <div style={{ padding: '0px 2px' }}>
                    <CurrentPageInput /> / <NumberOfPages />
                </div>
                <div style={{ padding: '0px 2px' }}>
                    <GoToNextPage />
                </div>
                <div style={{ padding: '0px 2px', marginLeft: 'auto' }}>
                    <EnterFullScreen />
                </div>
                <div style={{ padding: '0px 2px' }}>
                    <Print />
                </div>
            </>
        )
    }
}
</Toolbar>

(The sample code)

0%
/ 0