- PDF Viewer
- PDF Toolbar
- PDF More Actions Menu
- PDF Floating Toolbar
- PDF Document Tabs
- PDF View
- PDF Document Grid
- PDF Document Info
- PDF Page Navigation
- PDF Zoom Controls
- PDF Undo/Redo Buttons
- PDF Keyboard Shortcuts
- PDF Bookmark Sidebar
- PDF Thumbnail Sidebar
- PDF Search Panel
- PDF Attachment List
- PDF Annotation Layer
- PDF Annotation Toolbar
- PDF Annotation Inspector
- PDF Annotation Selection Menu
- PDF Annotation Sidebar
- PDF Comment
- PDF Comment Draft
- PDF Comment Button
- PDF Comment Sidebar
- PDF Redaction Toolbar
- PDF Capture Button
- PDF Form Fill Toggle
- PDF Signature Button
- PDF Stamp Button
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.
The toolbar renders nothing at all when the annotation plugin isn't registered. If it appears empty, that's the missing registration rather than a missing document.
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.
| Prop | Type | Default | Description |
|---|---|---|---|
tools | string[] | A common subset | Tool 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.