0

PDF Annotation Toolbar

Tool selection for the annotation plugin — highlight, draw, comment, and shapes.

"use client";

import { createPluginRegistration } from "@embedpdf/core";

About

<PdfAnnotationToolbar /> selects which annotation tool is active. Picking a tool arms the viewer; drawing, placing, and editing are handled by the annotation plugin's own layer once a tool is armed.

It's the "what am I about to make" half of annotating. The other half — what it looks like — is <PdfAnnotationInspector />, which styles the armed tool while nothing is selected and the selection itself once something is.

Annotation is a heavy-tier plugin, which means <PdfViewer /> does not register it for you. Two things have to be added before this toolbar renders anything: the plugin, and the layer that draws annotations onto the page. Both are shown below.

Installation

pnpm dlx shadcn@latest add pdfcn/annotation-toolbar

Usage

Register the annotation plugin.

import { createPluginRegistration } from "@embedpdf/core";
import { AnnotationPluginPackage } from "@embedpdf/plugin-annotation/react";
 
// Outside the component — a new array identity on every render tears the
// engine down and rebuilds it, losing scroll and zoom state.
const plugins = [createPluginRegistration(AnnotationPluginPackage)];

Render the annotation layer and the toolbar.

<PdfViewer
  documents={[{ url: "/sample.pdf" }]}
  plugins={plugins}
  className="h-[720px]"
>
  <PdfToolbar>
    <PdfAnnotationToolbar />
  </PdfToolbar>
  <PdfViewerContent
    pageLayers={({ documentId, pageIndex }) => (
      <PdfAnnotationLayer documentId={documentId} pageIndex={pageIndex} />
    )}
  />
</PdfViewer>

Without the pageLayers layer, tools still arm and annotations are still created — they just aren't drawn. The toolbar and the layer are two halves of the same feature.

Examples

Default

"use client";

import { createPluginRegistration } from "@embedpdf/core";

Choosing which tools to show

The plugin registers nineteen tools. The toolbar shows a common subset by default; pass tools to choose your own, in your own order:

<PdfAnnotationToolbar tools={["highlight", "underline", "ink"]} />

Ids that the plugin doesn't know are skipped rather than rendered empty, so narrowing the list is safe when a tool has been removed from the plugin's own configuration.

The full set of built-in ids: highlight, underline, strikeout, squiggly, insertText, replaceText, ink, inkHighlighter, circle, square, line, lineArrow, polyline, polygon, textComment, freeText, freeTextCallout, stamp, link. This set is embedpdf's; see its Annotation plugin for what each tool does and how to configure them.

Styling what you draw

The toolbar arms a tool; it doesn't style one. Pair it with <PdfAnnotationInspector />, which edits the armed tool's defaults while nothing is selected and restyles the selection once something is:

<PdfToolbar>
  <PdfAnnotationToolbar />
</PdfToolbar>
<div className="flex min-h-0 flex-1">
  <PdfViewerContent className="flex-1" pageLayers={/* … */} />
  <PdfAnnotationInspector className="w-72 border-l" />
</div>

When annotating is disabled

The toolbar reads the active document's modify-annotations permission and disables every tool — with a tooltip explaining why — when the flag is denied. The demo below forces the flag off with a permissions override; a real document carries it in its own flags. See Permissions for the full model.

"use client";

import { createPluginRegistration } from "@embedpdf/core";

Accessibility

The toolbar is a single-select <ToggleGroup />, so arrow keys move between tools and the armed tool is exposed through its pressed state rather than colour alone. Each tool is icon-only and carries an aria-label with the tool's name, matching its tooltip, so the label is available whether or not the tooltip is shown.

Annotating requires a pointer — tools arm from the keyboard, but drawing on the page has no keyboard equivalent.

API Reference

PdfAnnotationToolbar

A single-select <ToggleGroup /> carrying data-slot="pdf-annotation-toolbar", bound to the annotation plugin's active tool. Accepts every <ToggleGroup /> prop except value, which it owns.

PropTypeDefaultDescription
toolsstring[]A common subsetTool ids to render, in order.

Returns null when the document isn't loaded or the annotation plugin isn't registered. Selecting the armed tool again disarms it.

Tools carry data-slot="pdf-annotation-toolbar-item". Icons are mapped from tool id; a tool added through the plugin's addTool renders with a generic shape icon rather than being dropped.