A toggle that arms the pin tool so the next click on the page drops a comment.
"use client";
import { createPluginRegistration } from "@embedpdf/core";About#
<PdfCommentButton /> is the entry point to commenting. Pressing it arms the
annotation plugin's built-in textComment tool; the next click on a page drops
a comment pin. Each pin is a PDF Text annotation, which
<PdfCommentLayer /> draws on-page as an
avatar marker and <PdfCommentSidebar />
lists as a thread.
- Reflects the armed tool — the toggle's pressed state tracks whether
textCommentis the active tool, so it stays in sync when the tool is armed or disarmed from anywhere else. - Respects permissions — when the document forbids annotating, the toggle is disabled with a tooltip explaining why, rather than looking armable but doing nothing.
Comment pins come from the annotation plugin, a heavy-tier plugin
<PdfViewer /> doesn't register for you. Add the plugin and the comment layer
before this button does anything, both shown below.
The button renders nothing at all when the annotation plugin isn't registered. If it doesn't appear, that's the missing registration rather than a missing document.
Installation#
pnpm dlx shadcn@latest add @pdfviewcn/comment-button
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. `annotationAuthor` attributes the pins.
const plugins = [
createPluginRegistration(AnnotationPluginPackage, {
annotationAuthor: "You",
}),
];Render the comment layer and the button.
<PdfViewer
documents={[{ url: "/sample.pdf" }]}
plugins={plugins}
className="h-[720px]"
>
<PdfToolbar>
<PdfCommentButton />
</PdfToolbar>
<PdfViewerContent
pageLayers={({ documentId, pageIndex }) => (
<PdfCommentLayer documentId={documentId} pageIndex={pageIndex} />
)}
/>
</PdfViewer>The button arms the tool; the layer is what the click lands on.
<PdfCommentLayer /> is the annotation
layer with the composer, the avatar pin, and the thread wired in — mount a bare
<PdfAnnotationLayer> here instead and
the button still works, but a comment draws as the PDF spec's yellow note icon
with nothing to open.
Pair it with <PdfCommentSidebar /> to
read and reply to the threads the pins create.
Examples#
Default#
"use client";
import { createPluginRegistration } from "@embedpdf/core";With a thread on the pin#
A pin on its own is a marker. <PdfCommentLayer /> makes it a conversation — an avatar marker that opens its thread when picked, and a composer before the pin is ever written. See PDF Comment for the pieces it wires together.
"use client";
import { createPluginRegistration } from "@embedpdf/core";Alongside the annotation tools#
The button is an ordinary toggle, so it sits in a toolbar run next to
<PdfAnnotationToolbar />. Both read
the same active-tool state, so arming one disarms the other:
<PdfToolbar>
<PdfAnnotationToolbar />
<PdfToolbarSeparator />
<PdfCommentButton />
</PdfToolbar>Accessibility#
The button is shadcn's <Toggle /> — a real <button> with aria-pressed, reachable with Tab and operable with Enter or Space. It carries aria-label="Comment", matching its tooltip, so the label is available whether or not the tooltip is shown.
Pressed state is read from the plugin's active tool rather than tracked from the click, so arming or disarming the tool anywhere else — a keyboard shortcut, another control — is announced here too.
A document that forbids annotating disables the button rather than hiding it, keeping tab order stable, and the tooltip says why.
API Reference#
PdfCommentButton#
A <Toggle /> carrying data-slot="pdf-comment-button", bound to the annotation
plugin's active tool. Accepts every <Toggle /> prop except pressed and
value, which it owns.
Returns null when the document isn't loaded or the annotation plugin isn't
registered. It disables itself when the active document forbids modifying
annotations. See Permissions for the full model.