Annotations
Add highlights, links, sticky notes, shapes, stamps, and freehand drawings to PDF pages.
Annotations
Beta Feature
The annotations API is still in beta. While the core functionality is stable, the API may change in future releases.
PDF annotations add interactive and visual elements to pages - highlights, sticky notes, links, shapes, stamps, and freehand drawings.
import { PDF, rgb } from "@libpdf/core";
const pdf = PDF.create();
const page = pdf.addPage();
// Add a yellow highlight
page.addHighlightAnnotation({
rect: { x: 100, y: 700, width: 200, height: 14 },
color: rgb(1, 1, 0),
contents: "Important text",
});
// Add a link
page.addLinkAnnotation({
rect: { x: 100, y: 650, width: 150, height: 14 },
uri: "https://example.com",
});
const bytes = await pdf.save();Reading Annotations
const pdf = await PDF.load(existingBytes);
const page = pdf.getPage(0);
// Get all annotations
const annotations = page.getAnnotations();
for (const annot of annotations) {
console.log(annot.type, annot.contents);
}
// Get specific types
const highlights = page.getHighlightAnnotations();
const links = page.getLinkAnnotations();Text Markup Annotations
Mark up text with highlights, underlines, strikeouts, or squiggly lines.
addHighlightAnnotation(options)
| Param | Type | Default | Description |
|---|---|---|---|
rect | Rect | Single rectangle | |
rects | Rect[] | Multiple rectangles (multi-line) | |
quadPoints | number[][] | Raw quad points (rotated text) | |
color | Color | yellow | Highlight color |
opacity | number | 1 | Opacity (0-1) |
contents | string | Comment text | |
title | string | Author name |
Returns: PDFHighlightAnnotation
// Simple highlight
page.addHighlightAnnotation({
rect: { x: 100, y: 700, width: 200, height: 14 },
color: rgb(1, 1, 0),
});
// Multi-line selection
page.addHighlightAnnotation({
rects: [
{ x: 100, y: 700, width: 400, height: 14 },
{ x: 100, y: 680, width: 250, height: 14 },
],
color: rgb(0.5, 1, 0.5),
});addUnderlineAnnotation(options)
Same options as addHighlightAnnotation.
Returns: PDFUnderlineAnnotation
page.addUnderlineAnnotation({
rect: { x: 100, y: 700, width: 200, height: 14 },
color: rgb(0, 0, 1),
});addStrikeOutAnnotation(options)
Same options as addHighlightAnnotation.
Returns: PDFStrikeOutAnnotation
page.addStrikeOutAnnotation({
rect: { x: 100, y: 700, width: 200, height: 14 },
color: rgb(1, 0, 0),
});addSquigglyAnnotation(options)
Same options as addHighlightAnnotation. Draws a wavy underline.
Returns: PDFSquigglyAnnotation
page.addSquigglyAnnotation({
rect: { x: 100, y: 700, width: 200, height: 14 },
color: rgb(1, 0, 0),
});Link Annotations
addLinkAnnotation(options)
| Param | Type | Default | Description |
|---|---|---|---|
rect | Rect | required | Link area |
uri | string | External URL | |
destination | InternalLinkDestination | Internal page link | |
borderWidth | number | 0 | Border width |
borderColor | Color | Border color |
Returns: PDFLinkAnnotation
// External link
page.addLinkAnnotation({
rect: { x: 100, y: 600, width: 200, height: 20 },
uri: "https://example.com",
});
// Internal link to another page
const page2 = pdf.addPage();
page.addLinkAnnotation({
rect: { x: 100, y: 550, width: 200, height: 20 },
destination: { page: page2, type: "Fit" },
});
// With specific position
page.addLinkAnnotation({
rect: { x: 100, y: 500, width: 200, height: 20 },
destination: {
page: page2,
type: "XYZ",
left: 72,
top: 720,
zoom: 1.5,
},
});Destination Types:
| Type | Description | Parameters |
|---|---|---|
Fit | Fit entire page | none |
FitH | Fit page width | top |
FitV | Fit page height | left |
XYZ | Explicit position and zoom | left, top, zoom |
FitR | Fit rectangle | rect: [l, b, r, t] |
Text Annotations (Sticky Notes)
addTextAnnotation(options)
| Param | Type | Default | Description |
|---|---|---|---|
rect | Rect | required | Icon position |
contents | string | Note text | |
title | string | Author name | |
color | Color | yellow | Background color |
icon | TextAnnotationIcon | "Note" | Icon type |
open | boolean | false | Show popup immediately |
Returns: PDFTextAnnotation
page.addTextAnnotation({
rect: { x: 500, y: 700, width: 24, height: 24 },
contents: "This is a comment",
title: "Reviewer",
color: rgb(1, 1, 0.7),
icon: "Comment",
open: true,
});Icon Options: Note, Comment, Key, Help, NewParagraph, Paragraph, Insert
Shape Annotations
addLineAnnotation(options)
| Param | Type | Default | Description |
|---|---|---|---|
start | Point | required | Start point |
end | Point | required | End point |
color | Color | black | Line color |
width | number | 1 | Line width |
startStyle | LineEndingStyle | "None" | Start ending |
endStyle | LineEndingStyle | "None" | End ending |
interiorColor | Color | Fill for closed arrows | |
contents | string | Comment |
Returns: PDFLineAnnotation
// Simple line
page.addLineAnnotation({
start: { x: 100, y: 500 },
end: { x: 300, y: 500 },
color: rgb(0, 0, 0),
width: 2,
});
// With arrow
page.addLineAnnotation({
start: { x: 100, y: 450 },
end: { x: 300, y: 450 },
color: rgb(1, 0, 0),
endStyle: "ClosedArrow",
interiorColor: rgb(1, 0, 0),
});Line Ending Styles: None, Square, Circle, Diamond, OpenArrow, ClosedArrow, Butt, ROpenArrow, RClosedArrow, Slash
addSquareAnnotation(options)
| Param | Type | Default | Description |
|---|---|---|---|
rect | Rect | required | Rectangle bounds |
color | Color | black | Stroke color |
fillColor | Color | Fill color | |
borderWidth | number | 1 | Border width |
contents | string | Comment |
Returns: PDFSquareAnnotation
page.addSquareAnnotation({
rect: { x: 100, y: 400, width: 150, height: 100 },
color: rgb(0, 0, 1),
fillColor: rgb(0.9, 0.9, 1),
borderWidth: 2,
});addCircleAnnotation(options)
Same options as addSquareAnnotation. Draws an ellipse within the bounding rect.
Returns: PDFCircleAnnotation
page.addCircleAnnotation({
rect: { x: 300, y: 400, width: 100, height: 100 },
color: rgb(1, 0, 0),
fillColor: rgb(1, 0.9, 0.9),
borderWidth: 2,
});Stamp Annotations
addStampAnnotation(options)
| Param | Type | Default | Description |
|---|---|---|---|
rect | Rect | required | Stamp bounds |
name | StampName | string | "Draft" | Stamp type |
contents | string | Comment |
Returns: PDFStampAnnotation
page.addStampAnnotation({
rect: { x: 400, y: 500, width: 120, height: 40 },
name: "Approved",
});Standard Stamps: Approved, NotApproved, Draft, Final, Confidential, Experimental, Expired, NotForPublicRelease, ForPublicRelease, ForComment, TopSecret, Departmental, AsIs, Sold
Ink Annotations (Freehand)
addInkAnnotation(options)
| Param | Type | Default | Description |
|---|---|---|---|
paths | Point[][] | required | Array of stroke paths |
color | Color | black | Stroke color |
width | number | 1 | Stroke width |
contents | string | Comment |
Returns: PDFInkAnnotation
page.addInkAnnotation({
paths: [
[
{ x: 100, y: 300 },
{ x: 150, y: 350 },
{ x: 200, y: 300 },
],
],
color: rgb(0, 0, 1),
width: 2,
});Modifying Annotations
const highlights = page.getHighlightAnnotations();
const highlight = highlights[0];
// Update properties
highlight.setContents("Updated comment");
highlight.setColor(rgb(0, 1, 0));
highlight.setHidden(false);
highlight.setPrintable(true);Removing Annotations
removeAnnotation(annotation)
Remove a specific annotation.
const highlights = page.getHighlightAnnotations();
page.removeAnnotation(highlights[0]);removeAnnotations(options?)
Remove annotations, optionally filtered by type.
| Param | Type | Description |
|---|---|---|
[options.type] | AnnotationSubtype | Filter by type |
// Remove all highlights
page.removeAnnotations({ type: "Highlight" });
// Remove all annotations
page.removeAnnotations();Common Properties
All annotations have these properties:
| Property | Type | Description |
|---|---|---|
type | AnnotationSubtype | Annotation type |
rect | Rect | Bounding rectangle |
contents | string | null | Text content |
color | Color | null | Annotation color |
isHidden | boolean | Hidden state |
isPrintable | boolean | Printable state |
isModified | boolean | Modified state |
Types
Rect
interface Rect {
x: number; // Left edge
y: number; // Bottom edge
width: number;
height: number;
}Point
interface Point {
x: number;
y: number;
}AnnotationFlags
import { AnnotationFlags } from "@libpdf/core";
// Check flags
if (annotation.hasFlag(AnnotationFlags.Print)) {
console.log("Will print");
}
// Set flags
annotation.setFlag(AnnotationFlags.ReadOnly, true);| Flag | Description |
|---|---|
Invisible | Don't display unknown types |
Hidden | Don't display or print |
Print | Print when page is printed |
NoZoom | Don't scale with zoom |
NoRotate | Don't rotate with page |
NoView | Don't display on screen |
ReadOnly | Don't allow interaction |
Locked | Don't allow deletion |
LockedContents | Don't allow content changes |
