# Imperative API

Command the viewer from your own buttons and code through a ref, and read its current page, zoom and status.

## Basics

A `ref` on `PdfViewer` gives you methods to navigate, zoom, rotate and go fullscreen.

**Demo: Buttons outside the viewer**

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

export default function Demo() {
  const viewer = useRef<PdfViewerApi>(null);

  return (
    <>
      <p className="demo-controls">
        <button type="button" className="demo-button" onClick={() => viewer.current?.goToPage(20)}>
          Page 20
        </button>
        <button type="button" className="demo-button" onClick={() => viewer.current?.setScale(2)}>
          Zoom to 200%
        </button>
        <button type="button" className="demo-button" onClick={() => viewer.current?.rotate('ccw')}>
          Rotate left
        </button>
        <button
          type="button"
          className="demo-button"
          onClick={() => viewer.current?.toggleFullscreen()}
        >
          Fullscreen
        </button>
      </p>
      <PdfViewer ref={viewer} source="/samples/multipage.pdf" />
    </>
  );
}
```

```tsx
const viewer = useRef<PdfViewerApi>(null);

<PdfViewer ref={viewer} source={url} />;

viewer.current?.goToPage(3);
```

| Read                                                                                       | Do                                                                                                                                                               |
| ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`, `numPages`, `page`, `scale`, `rotation`, `fullscreen`, `canZoomIn`, `canZoomOut` | `goToPage`, `nextPage`, `previousPage`, `zoomIn`, `zoomOut`, `setScale`, `resetZoom`, `rotate`, `toggleFullscreen`, `download`, `print`, `reload`, `getDocument` |

The same object is passed to [`renderToolbar`](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/custom-toolbar/). Its values are a snapshot of the render that produced it: read them from `ref.current` when you need them, rather than keeping an old copy. Every member is documented in the [`PdfViewerApi` reference](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/pdf-viewer-api/).

## Customization

Hide the toolbar and build the whole interface from the API: download, print, reload, or read document metadata through PDF.js.

**Demo: A toolbar-less viewer driven by your buttons**

```tsx
import { PdfViewer, type PdfViewerApi } from '@kingtech/react-pdf-viewer';
import { useRef, useState } from 'react';

export default function Demo() {
  const viewer = useRef<PdfViewerApi>(null);
  const [info, setInfo] = useState('');

  return (
    <>
      <p className="demo-controls">
        <button
          type="button"
          className="demo-button"
          onClick={() => void viewer.current?.download()}
        >
          Download
        </button>
        <button type="button" className="demo-button" onClick={() => void viewer.current?.print()}>
          Print
        </button>
        <button type="button" className="demo-button" onClick={() => viewer.current?.reload()}>
          Reload
        </button>
        <button
          type="button"
          className="demo-button"
          onClick={async () => {
            const document = viewer.current?.getDocument();
            const metadata = await document?.getMetadata();
            setInfo(JSON.stringify(metadata?.info ?? {}, null, 2));
          }}
        >
          Read metadata
        </button>
      </p>
      {/* Toolbar hidden: the buttons above are the whole interface. */}
      <PdfViewer ref={viewer} source="/samples/letter-3pages.pdf" toolbar={false} />
      {info && <pre className="demo-output">{info}</pre>}
    </>
  );
}
```

See the [customization guide](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/customization/).

## Advanced / escape hatch

`getDocument()` returns the loaded PDF.js `PDFDocumentProxy` (or `null`) for anything the viewer does not wrap: metadata, the outline, attachments or text extraction. Do not destroy it; the viewer owns its lifecycle.

## Limitations

- **Values are a snapshot.** An API object captured in an old closure reports old values. Workaround: read from `ref.current` at the time you need the value, or use the `onXChange` [events](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/events/).
- **`ref.current` is `null` before mount.** Workaround: guard with optional chaining, as in the examples.
- **The PDF.js document is not a stable API of this package.** Its methods follow `pdfjs-dist`. Workaround: pin `pdfjs-dist` when you depend on them.

## API

- [PdfViewerApi](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/pdf-viewer-api.md)

---

## PdfViewerApi reference

Imperative viewer API, available through `ref` and passed to `renderToolbar`. Values are a
snapshot of the render that produced the object.

### Used by

- [Imperative API](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/imperative-api.md)

### Import

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

### Properties

| Name | Type | Default | Required | Description |
| --- | --- | --- | --- | --- |
| `status` | `PdfDocumentStatus` | — | Yes | Document status. |
| `numPages` | `number` | — | Yes | Page count; `0` without a document. |
| `page` | `number` | — | Yes | Current 1-based page, clamped to the document. |
| `scale` | `number` | — | Yes | Current scale (`1` = 100%). |
| `rotation` | `Rotation` | — | Yes | Current user rotation. |
| `fullscreen` | `boolean` | — | Yes | Whether the viewer is in fullscreen. |
| `canZoomIn` | `boolean` | — | Yes | Whether `zoomIn()` would change the scale. |
| `canZoomOut` | `boolean` | — | Yes | Whether `zoomOut()` would change the scale. |
| `goToPage` | `(page: number) => void` | — | No | Go to a page (clamped). |
| `nextPage` | `() => void` | — | No | Next page. |
| `previousPage` | `() => void` | — | No | Previous page. |
| `zoomIn` | `() => void` | — | No | One step (or preset) up. |
| `zoomOut` | `() => void` | — | No | One step (or preset) down. |
| `setScale` | `(scale: number) => void` | — | No | Set the scale, clamped to `[minScale, maxScale]`. |
| `resetZoom` | `() => void` | — | No | Return to `defaultScale`. |
| `rotate` | `(direction?: 'cw' \| 'ccw') => void` | — | No | Rotate by 90°, clockwise by default. |
| `toggleFullscreen` | `() => void` | — | No | Enter or leave fullscreen. |
| `download` | `() => Promise<void>` | — | No | Save the loaded document (no second request). |
| `print` | `() => Promise<void>` | — | No | Print according to `printMode`. |
| `reload` | `() => void` | — | No | Load the source again, e.g. after an error. |
| `getDocument` | `() => PDFDocumentProxy \| null` | — | No | The loaded PDF.js document, for advanced use. Do not destroy it. |

### Source

[packages/react-pdf-viewer/src/types.ts](https://github.com/kiralygyula92/react-pdf-viewer/blob/main/packages/react-pdf-viewer/src/types.ts#L153)

