# Page navigation

Build labeled previous and next buttons and jump to a specific page.

Source: https://anara.com/lector/docs/code/page-navigation

These docs describe the source deployed with this site, tracking main rather than a versioned npm release. Check your installed @anaralabs/lector and pdfjs-dist versions before applying examples.

Use `usePdfJump` to move the scroll viewport. Lector's page numbers start at **1**, including `currentPage` and `jumpToPage(1)`.

## Previous, next, and direct input

This toolbar is a complete component. Mount `<PageControls />` **inside `Root`**, above the bounded `Pages` wrapper from [your first viewer](https://anara.com/lector/docs/basic-usage).

```tsx title="page-controls.tsx"
"use client";

import { CurrentPage, TotalPages, usePdf, usePdfJump } from "@anaralabs/lector";

export default function PageControls() {
  const page = usePdf((state) => state.currentPage);
  const total = usePdf((state) => state.pdfDocumentProxy.numPages);
  const { jumpToPage } = usePdfJump();

  return (
    <div role="group" aria-label="Page navigation" style={{ display: "flex", gap: 8 }}>
      <button
        type="button"
        disabled={page <= 1}
        onClick={() => jumpToPage(page - 1, { behavior: "auto" })}
      >
        Previous page
      </button>
      <label>Page <CurrentPage style={{ width: 56 }} /></label>
      <span>of</span>
      <TotalPages />
      <button
        type="button"
        disabled={page >= total}
        onClick={() => jumpToPage(page + 1, { behavior: "auto" })}
      >
        Next page
      </button>
    </div>
  );
}
```

`CurrentPage` updates as you scroll. Its input commits on blur or Enter. For your own input, validate an integer from `1` through `numPages` before calling `jumpToPage`; that hook does not validate the range for you.

The exported `NextPage` and `PreviousPage` components are currently placeholders. Use the hook-based buttons above.

## Jump options

```ts
jumpToPage(3, { align: "start", behavior: "auto" });
```

| Option     | Values                                   | Default    |
| ---------- | ---------------------------------------- | ---------- |
| `align`    | `"start"`, `"center"`, `"end"`, `"auto"` | `"start"`  |
| `behavior` | `"auto"`, `"smooth"`                     | `"smooth"` |

Use `"auto"` for immediate jumps and when the user prefers reduced motion. `jumpToPage` needs a mounted `Pages` container; before its virtualizer exists, the call does nothing. Changing `setCurrentPage` alone changes store state but does not scroll.

## Restore a reading position

`Pages` accepts `initialOffset` in scroll pixels and reports changes through `onOffsetChange`. Save the offset under a document-specific key, then pass it when mounting that document again. The current callback only reports nonzero offsets, so reset a saved position explicitly when your app returns to the top.

Offsets depend on zoom, page sizes, and layout. For bookmarks that need to survive layout changes, save a page number or a [highlight region](https://anara.com/lector/docs/code/highlight) instead.

## Live example

Open the documentation page linked above to use this interactive example.
