# Custom toolbar

Replace the toolbar with your own controls, or combine parts of the built-in toolbar with buttons of your own.

## Basics

`renderToolbar(api)` replaces the toolbar with anything you render, driven by the [viewer API](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/imperative-api/).

**Demo: Your own controls**

```tsx
import { PdfViewer } from '@kingtech/react-pdf-viewer';

export default function Demo() {
  return (
    <PdfViewer
      source="/samples/multipage.pdf"
      toolbar={{ position: 'top' }}
      renderToolbar={(api) => (
        <div className="demo-controls" role="group" aria-label="Document controls">
          <button
            type="button"
            className="demo-button"
            onClick={api.previousPage}
            disabled={api.page <= 1}
          >
            ← Back
          </button>
          <span aria-live="polite">
            Page {api.page} of {api.numPages}
          </span>
          <button
            type="button"
            className="demo-button"
            onClick={api.nextPage}
            disabled={api.page >= api.numPages}
          >
            Next →
          </button>
          <select
            aria-label="Zoom"
            value={String(api.scale)}
            onChange={(event) => api.setScale(Number(event.target.value))}
          >
            {[0.5, 0.75, 1, 1.5, 2].map((scale) => (
              <option key={scale} value={String(scale)}>
                {scale * 100}%
              </option>
            ))}
          </select>
          <button type="button" className="demo-button" onClick={() => void api.download()}>
            Download
          </button>
        </div>
      )}
    />
  );
}
```

The custom toolbar sits where the built-in one would, honoring `toolbar.position`. It re-renders with a fresh `api` whenever page, zoom, rotation or status change.

### Reusing the built-in toolbar

`PdfToolbar` is the built-in toolbar as a component. Render it with a subset of actions next to your own buttons.

**Demo: Built-in navigation plus a custom print button**

```tsx
import { PdfToolbar, PdfViewer } from '@kingtech/react-pdf-viewer';

export default function Demo() {
  return (
    <PdfViewer
      source="/samples/multipage.pdf"
      renderToolbar={(api) => (
        <div
          style={{
            display: 'flex',
            flexWrap: 'wrap',
            gap: 12,
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          <PdfToolbar
            api={api}
            config={{ actions: ['previousPage', 'pageIndicator', 'nextPage'] }}
          />
          <button type="button" onClick={() => void api.print()}>
            Print this report
          </button>
        </div>
      )}
    />
  );
}
```

`PdfToolbar` keeps its accessibility (single tab stop, arrow-key navigation, the responsive **More actions** menu) wherever you place it.

## Customization

`PdfToolbar` takes `config`, `labels`, `locale`, `compact`, `zoomReset`, a replacement `pageIndicator` and `menuPlacement`.

**Demo: A wider toolbar with a custom page indicator**

```tsx
import { PdfToolbar, PdfViewer } from '@kingtech/react-pdf-viewer';
import type { CSSProperties } from 'react';

const style = {
  '--rpv-toolbar-bg': '#115e59',
  '--rpv-toolbar-max-width': '640px',
} as CSSProperties;

export default function Demo() {
  return (
    <PdfViewer
      source="/samples/letter-3pages.pdf"
      toolbar={{ position: 'top' }}
      style={style}
      renderToolbar={(api) => (
        <PdfToolbar
          api={api}
          zoomReset
          menuPlacement="bottom"
          labels={{ moreActions: 'More' }}
          pageIndicator={
            <span>
              {api.page} ∕ {api.numPages}
            </span>
          }
        />
      )}
    />
  );
}
```

Every prop is listed in the [`PdfToolbarProps` reference](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/pdf-toolbar-props/); see also the [customization guide](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/customization/).

## Advanced / escape hatch

Hide the toolbar (`toolbar={false}`) and render controls anywhere in your layout with a [ref](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/imperative-api/), or build a viewer from scratch with the [headless](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/headless/) pieces.

> **Warning: Accessibility is yours in a custom toolbar**
>
> A `renderToolbar` UI replaces the built-in keyboard and screen reader behavior. Label every
>   control, keep disabled states in sync with `canZoomIn`, `canZoomOut`, `page` and `numPages`, and
>   announce page changes, as the first demo does with `aria-live`.

## Limitations

- **One toolbar slot.** `renderToolbar` renders in the toolbar position only. Workaround: hide the toolbar and place controls anywhere with a ref.
- **`PdfToolbar` needs a viewer API.** It cannot drive a headless `PdfPageCanvas` directly. Workaround: build headless controls from `usePdfDocument` state.

## API

- [PdfToolbar](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/pdf-toolbar.md)
- [PdfToolbarProps](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/pdf-toolbar-props.md)

---

## PdfToolbar reference

The default toolbar: zoom, page navigation, fullscreen, rotate, download and print, on one row.

When the row does not fit, secondary actions collapse into a “More actions” menu. Usable on its own, for example inside `renderToolbar`.

### Used by

- [Custom toolbar](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/custom-toolbar.md)

### Import

```ts
import { PdfToolbar } from '@kingtech/react-pdf-viewer';
```

### Props

| Name | Type | Default | Required | Description |
| --- | --- | --- | --- | --- |
| `api` | `PdfViewerApi` | — | Yes | The viewer API, from a `ref` or `renderToolbar`. |
| `labels` | `Partial<PdfViewerLabels>` | — | No | Label overrides. |
| `config` | `ToolbarConfig` | — | No | Which actions to show. |
| `compact` | `boolean` | — | No | Compact layout: hides `hiddenWhenCompact` actions outside fullscreen. |
| `locale` | `string` | — | No | Locale for number formatting. |
| `zoomReset` | `boolean` | `false` | No | The zoom label becomes a reset button. |
| `pageIndicator` | `ReactNode` | — | No | Replaces the page indicator text, e.g. with your own input. |
| `menuPlacement` | `'top' \| 'bottom'` | — | No | Where the More actions menu opens. `PdfViewer` picks the side away from the edge. |

### Source

[packages/react-pdf-viewer/src/components/Toolbar.tsx](https://github.com/kiralygyula92/react-pdf-viewer/blob/main/packages/react-pdf-viewer/src/components/Toolbar.tsx#L412)


---

## PdfToolbarProps reference

Props for `PdfToolbar`: the viewer API it controls, its labels and configuration, the compact layout and the page indicator slot.

### Used by

- [Custom toolbar](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/custom-toolbar.md)

### Import

```ts
import type { PdfToolbarProps } from '@kingtech/react-pdf-viewer';
```

### Properties

| Name | Type | Default | Required | Description |
| --- | --- | --- | --- | --- |
| `api` | `PdfViewerApi` | — | Yes | The viewer API, from a `ref` or `renderToolbar`. |
| `labels` | `Partial<PdfViewerLabels>` | — | No | Label overrides. |
| `config` | `ToolbarConfig` | — | No | Which actions to show. |
| `compact` | `boolean` | — | No | Compact layout: hides `hiddenWhenCompact` actions outside fullscreen. |
| `locale` | `string` | — | No | Locale for number formatting. |
| `zoomReset` | `boolean` | `false` | No | The zoom label becomes a reset button. |
| `pageIndicator` | `ReactNode` | — | No | Replaces the page indicator text, e.g. with your own input. |
| `menuPlacement` | `'top' \| 'bottom'` | — | No | Where the More actions menu opens. `PdfViewer` picks the side away from the edge. |

### Source

[packages/react-pdf-viewer/src/components/Toolbar.tsx](https://github.com/kiralygyula92/react-pdf-viewer/blob/main/packages/react-pdf-viewer/src/components/Toolbar.tsx#L95)

