Skip to content

Customizing Toolbar

Overview of the Toolbar

React PDF features a flexible toolbar with RPDefaultLayout component which can be configured to show or hide a top bar and a left sidebar. This provides an intuitive interface for navigating and interacting with PDF documents.

By default, all tools are enabled, giving users immediate access to the full range of features out-of-the-box without any additional configurations. However, React PDF also offers customization options, allowing you to tailor the toolbar to fit your specific use case.

Let’s take a closer look at the tutorial below to learn how to customize and adapt the toolbar to your needs.

To get started, explore the available configuration options in the RPDefault Layout Component.

Use Existing Slots

React PDF allows you to override the behavior of a tool in the toolbar to extend or modify each default functionality based on your application’s needs.

For a complete list of slots available for customizing tools, refer to the RPSlot - Tools documentation.

Example: Customizing the zoomTool

You can use the zoomTool slot to customize how the zoom functionality behaves in the viewer. In this example, custom buttons are added to adjust the zoom scale. The zoom function is used to increase or decrease the zoom level by a specified amount, and the currentScale is displayed in the middle.

import { useCallback } from 'react'
import {
RPConfig,
RPProvider,
RPDefaultLayout,
RPPages,
} from '@pdf-viewer/react'
const CustomZoomLayout = ({zoomLevel, setZoomLevel}) => {
// zoom in 10 and max 1000
const handleZoomIn = useCallback(() => {
setZoomLevel((prev) => Math.min(prev + 10, 1000))
}, [setZoomLevel])
// zoom out 10 and min 10 to prevent scale to be less than 1
const handleZoomOut = useCallback(() => {
setZoomLevel((prev) => Math.max(prev - 10, 10))
}, [setZoomLevel])
return (
<div>
<button onClick={handleZoomIn}> Zoom In </button>
{zoomLevel}
<button onClick={handleZoomOut}> Zoom Out </button>
</div>
)
}
export const AppPdfViewer = () => {
return (
<RPConfig>
<RPProvider src="https://cdn.codewithmosh.com/image/upload/v1721763853/guides/web-roadmap.pdf">
<RPDefaultLayout
style={{ width : "100%" , height: '550px' }}
slots={{
zoomTool: CustomZoomLayout
}}
>
<RPPages />
</RPDefaultLayout>
</RPProvider>
</RPConfig>
)
}
  • The Zoom Out button decreases the zoom level by 10 percent.
  • The Zoom In button increases the zoom level by 10 percent.
  • The zoom level value is displayed between the buttons to show the current zoom level.

Image of customizing zoomTool on the top bar

Using Custom Buttons/Icons with React Hooks

Certain tools within the toolbar and More Options menu expose a React Context API, enabling advanced control and customization. These APIs allow developers to interact with and modify the behavior of specific tools directly from the parent component.

The methods are exposed through React’s hooks and can be accessed via a ref in the parent component. This setup allows developers to dynamically trigger actions, such as adjusting zoom levels, toggling visibility, or navigating pages. For a detailed list of available configuration options, refer to the Hooks documentation.

Show Tool from ‘More Options’ in the Top Bar

By default, the tools available in the ‘More Options’ menu are not shown in the top bar. However, you can use the React PDF’s React Context API to selectively display specific tools directly in the top bar, providing a more tailored user experience. Image of the menu list in More Options

Example: Displaying Rotate Tool on the Top Bar

By default, the Rotate Clockwise and Rotate Counterclockwise tools are located within the More Options menu. This example demonstrates how to use the React Context API to display these tools directly on the top bar for better accessibility.

Step 1: Creating button Element

Start by creating two button elements using useMemo—one for rotating clockwise (↻) and one for counterclockwise (↺). This ensures the buttons are only created once and reused efficiently.

const buttonRotateClockwise = useMemo(() => {
const button = document.createElement("button");
button.innerHTML = "↻";
return button;
}, []);
const buttonRotateCounterclockwise = useMemo(() => {
const button = document.createElement("button");
button.innerHTML = "↺";
return button;
}, []);

Step 2: Create Rotation Handlers

Define two functions to handle rotation. Each updates the rotation state by 90 degrees—clockwise or counterclockwise—using useCallback to optimize performance.

// Rotate 90 degrees in a clockwise direction
const handleRotateClockwise = useCallback(() => {
setRotate((prev) => (prev + 90) % 360)
}, [setRotate])
// Rotate 90 degrees in a counterclockwise direction
const handleRotateCounterclockwise = useCallback(() => {
setRotate((prev) => (prev - 90 + 360) % 360)
}, [setRotate])

Step 3: Add Buttons to the Top Bar

Use the handleLoaded function to insert your custom rotate buttons into the viewer’s top bar. This targets the top bar element and prepends both buttons after the viewer loads.

const handleLoaded = useCallback(() => {
// Get the element of React PDF.
const topBarRight = ref.current?.querySelector('[data-rp="topBarRight"]');
// Add the button element to the top bar.
topBarRight?.prepend(buttonRotateClockwise);
topBarRight?.prepend(buttonRotateCounterclockwise);
}, [buttonRotateClockwise]);

Step 4: Clean Up Buttons on Unmount

Define a cleanup function to remove the rotate buttons when the component unmounts. This prevents duplicate buttons if the viewer reloads or re-renders.

const cleanupOnLoaded = useCallback(() => {
if (buttonRotateClockwise) {
buttonRotateClockwise.remove();
}
if (buttonRotateCounterclockwise) {
buttonRotateCounterclockwise.remove();
}
}, [buttonRotateClockwise, buttonRotateCounterclockwise]);

Step 5: Connect Buttons to the PDF Viewer

Pass the handleLoaded and cleanupOnLoaded functions to the viewer layout. This hooks your custom buttons into the viewer when it loads and removes them when it unmounts.

export const AppPdfViewer = () => {
return (
<RPDefaultLayout
ref={ref}
onLoaded={handleLoaded}
cleanupOnLoaded={cleanupOnLoaded}
style={{ width : "100%" , height: '550px' }}
>
<RPPages />
</RPDefaultLayout>
)
}

Here are the full codes for this example:

// App.jsx (Parent Component)
import { RPConfig, RPProvider } from "@pdf-viewer/react";
import { AppPdfViewer } from "./components/AppPdfViewer";
export default function App{
return (
<RPConfig>
<RPProvider src="https://cdn.codewithmosh.com/image/upload/v1721763853/guides/web-roadmap.pdf">
<AppPdfViewer />
</RPProvider>
</RPConfig>
)
}
// AppPdfViewer.jsx (Child Component)
import React, { useCallback, useMemo, useRef } from "react";
export const AppPdfViewer = () => {
const { rotate, setRotate } = useRotationContext();
const ref = useRef<HTMLDivElement>(null);
// Rotate 90 degrees in a clockwise direction
const handleRotateClockwise = useCallback(() => {
setRotate((prev) => (prev + 90) % 360);
}, [setRotate]);
// Rotate 90 degrees in a counterclockwise direction
const handleRotateCounterclockwise = useCallback(() => {
setRotate((prev) => (prev - 90 + 360) % 360);
}, [setRotate]);
// Create the button element.
const buttonRotateClockwise = useMemo(() => {
const button = document.createElement("button");
button.innerHTML = "↻";
button.onclick = handleRotateClockwise;
return button;
}, []);
const buttonRotateCounterclockwise = useMemo(() => {
const button = document.createElement("button");
button.innerHTML = "↺";
button.onclick = handleRotateCounterclockwise;
return button;
}, []);
const handleLoaded = useCallback(() => {
// Get the element of React PDF.
const topBarRight = ref.current?.querySelector('[data-rp="topBarRight"]');
// Add the button element to the top bar.
topBarRight?.prepend(buttonRotateClockwise);
topBarRight?.prepend(buttonRotateCounterclockwise);
}, [buttonRotateClockwise]);
// Remove the button element when the component is cleaned up.
const cleanupOnLoaded = useCallback(() => {
if (buttonRotateClockwise) {
buttonRotateClockwise.remove();
}
if (buttonRotateCounterclockwise) {
buttonRotateCounterclockwise.remove();
}
}, [buttonRotateClockwise, buttonRotateCounterclockwise]);
return (
<>
<RPDefaultLayout
ref={ref}
style={{ width: "100%", height: "550px" }}
onLoaded={handleLoaded}
cleanupOnLoaded={cleanupOnLoaded}
>
<RPPages />
</RPDefaultLayout>
</>
);
};

Result example of rotate icons being shown on the top bar

Adding Custom Buttons in a Parent Component

With the React Contenxt API, you can invoke key features like rotating pages, zooming, or navigating through the document without relying solely on the viewer’s built-in UI. This approach is particularly useful for users who need to customize specific designs or meet unique usability requirements.

Example: External Button to Trigger a Rotate Function

React PDF provides a useRotationContext through its React Context API, enabling you to control page rotation from outside the viewer. This flexibility allows you to integrate rotation controls into custom buttons or external components, making the viewer adaptable to your application’s needs.

Here are the available functions for managing page rotation using the Rotate Context.

import {
useRotationContext,
RPConfig,
RPProvider,
RPDefaultLayout,
RPPages
} from "@pdf-viewer/react";
const CustomRotationLayout = () => {
// Access the rotation control from the context
const { rotate, setRotate } = useRotationContext();
// Rotate 90 degrees in a clockwise direction
const handleRotateClockwise = () => {
setRotate((prev) => (prev + 90) % 360);
};
// Rotate 90 degrees in a counterclockwise direction
const handleRotateCounterclockwise = () => {
setRotate((prev) => (prev - 90 + 360) % 360);
};
return (
<div>
{rotate} degrees
<br />
<button onClick={handleRotateClockwise}>Rotate Clockwise</button>
<br />
<button onClick={handleRotateCounterclockwise}>
Rotate Counterclockwise
</button>
</div>
);
};
export const AppPdfViewer = () => {
return (
<RPConfig>
<RPProvider src="https://cdn.codewithmosh.com/image/upload/v1721763853/guides/web-roadmap.pdf">
<CustomRotationLayout/>
<RPDefaultLayout
style={{ width: "100%", height: "550px" }}
>
<RPPages />
</RPDefaultLayout>
</RPProvider>
</RPConfig>
);
};

Image of adding a rotate function outside of the PDF Viewer