react-pdf-highlighter-plus
v1.0.8
Published
Set of modern React components for PDF highlighting
Maintainers
Readme
react-pdf-highlighter-plus
Overview
react-pdf-highlighter-plus provides a highly customizable annotation experience for PDF documents in React applications. Built on PDF.js, it stores highlight positions in viewport-independent coordinates, making them portable across different screen sizes.
Features
| Feature | Description | |---------|-------------| | Text Highlights | Select and highlight text passages | | Area Highlights | Draw rectangular regions on PDFs | | Freetext Notes | Draggable, editable sticky notes with custom styling | | Images & Signatures | Upload images or draw signatures directly on PDFs | | Freehand Drawing | Draw freehand annotations with customizable stroke | | PDF Export | Export annotated PDF with all highlights embedded | | Zoom Support | Full zoom functionality with position-independent data | | Fully Customizable | Exposed styling on all components |
Quick Links
| Resource | Link | |----------|------| | Live Demo | View Demo | | Documentation | API Docs | | NPM Package | npm |
Installation
npm install react-pdf-highlighter-plusImport Styles
import "react-pdf-highlighter-plus/style/style.css";Quick Start
Basic Setup
import {
PdfLoader,
PdfHighlighter,
TextHighlight,
AreaHighlight,
useHighlightContainerContext,
} from "react-pdf-highlighter-plus";
import "react-pdf-highlighter-plus/style/style.css";
function App() {
const [highlights, setHighlights] = useState([]);
return (
<PdfLoader document="https://example.com/document.pdf">
{(pdfDocument) => (
<PdfHighlighter
pdfDocument={pdfDocument}
highlights={highlights}
enableAreaSelection={(e) => e.altKey}
>
<HighlightContainer />
</PdfHighlighter>
)}
</PdfLoader>
);
}
function HighlightContainer() {
const { highlight, isScrolledTo } = useHighlightContainerContext();
return highlight.type === "text" ? (
<TextHighlight highlight={highlight} isScrolledTo={isScrolledTo} />
) : (
<AreaHighlight highlight={highlight} isScrolledTo={isScrolledTo} />
);
}Highlight Types
1. Text Highlights
Select text in the PDF to create highlights.
<TextHighlight
highlight={highlight}
isScrolledTo={isScrolledTo}
style={{ background: "rgba(255, 226, 143, 1)" }}
/>2. Area Highlights
Hold Alt and drag to create rectangular highlights.
<PdfHighlighter
enableAreaSelection={(event) => event.altKey}
// ...
>3. Freetext Notes
Create draggable, editable text annotations with customizable styling.
import { FreetextHighlight } from "react-pdf-highlighter-plus";
<PdfHighlighter
enableFreetextCreation={() => freetextMode}
onFreetextClick={(position) => {
addHighlight({ type: "freetext", position, content: { text: "Note" } });
}}
>
// In your highlight container:
<FreetextHighlight
highlight={highlight}
onChange={handlePositionChange}
onTextChange={handleTextChange}
onStyleChange={handleStyleChange}
color="#333333"
backgroundColor="#ffffc8"
fontSize="14px"
/>Features:
- Drag to reposition
- Click to edit text
- Built-in style panel (colors, font size, font family)
- Toolbar appears on hover
4. Images & Signatures
Upload images or draw signatures and place them on PDFs.
import { ImageHighlight, SignaturePad } from "react-pdf-highlighter-plus";
// Signature pad modal
<SignaturePad
isOpen={isOpen}
onComplete={(dataUrl) => setPendingImage(dataUrl)}
onClose={() => setIsOpen(false)}
/>
// In your highlight container:
<ImageHighlight
highlight={highlight}
onChange={handlePositionChange}
onEditStart={() => toggleEditInProgress(true)}
onEditEnd={() => toggleEditInProgress(false)}
/>Features:
- Upload any image format
- Draw signatures with mouse or touch
- Drag to reposition
- Resize while maintaining aspect ratio
- Toolbar appears on hover
5. Freehand Drawing
Draw freehand annotations directly on PDFs.
import { DrawingHighlight } from "react-pdf-highlighter-plus";
<PdfHighlighter
enableDrawingCreation={() => drawingMode}
onDrawingComplete={(position, dataUrl) => {
addHighlight({ type: "drawing", position, content: { image: dataUrl } });
}}
drawingConfig={{
strokeColor: "#ff0000",
strokeWidth: 2,
}}
>
// In your highlight container:
<DrawingHighlight
highlight={highlight}
onChange={handlePositionChange}
/>Features:
- Freehand drawing with mouse or touch
- Customizable stroke color and width
- Stored as PNG for PDF export compatibility
- Drag to reposition
PDF Export
Export your annotated PDF with all highlights embedded.
import { exportPdf } from "react-pdf-highlighter-plus";
const handleExport = async () => {
const pdfBytes = await exportPdf(pdfUrl, highlights, {
textHighlightColor: "rgba(255, 226, 143, 0.5)",
areaHighlightColor: "rgba(255, 226, 143, 0.5)",
onProgress: (current, total) => console.log(`${current}/${total} pages`),
});
// Download the file
const blob = new Blob([pdfBytes], { type: "application/pdf" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "annotated.pdf";
a.click();
URL.revokeObjectURL(url);
};Supported highlight types:
- Text highlights (colored rectangles)
- Area highlights (colored rectangles)
- Freetext notes (background + wrapped text)
- Images & signatures (embedded PNG/JPG)
- Freehand drawings (embedded PNG)
Component Architecture
┌─────────────────────────────────────────────────────┐
│ PdfLoader │
│ Loads PDF document via PDF.js │
│ │
│ ┌───────────────────────────────────────────────┐ │
│ │ PdfHighlighter │ │
│ │ Manages viewer, events, coordinate systems │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ User-defined HighlightContainer │ │ │
│ │ │ Renders highlights using context hooks │ │ │
│ │ │ │ │ │
│ │ │ • TextHighlight │ │ │
│ │ │ • AreaHighlight │ │ │
│ │ │ • FreetextHighlight │ │ │
│ │ │ • ImageHighlight │ │ │
│ │ │ • DrawingHighlight │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘Context Hooks
| Hook | Purpose |
|------|---------|
| usePdfHighlighterContext() | Viewer utilities: scrollToHighlight, setTip, getCurrentSelection |
| useHighlightContainerContext() | Per-highlight utilities: highlight, viewportToScaled, screenshot |
Coordinate Systems
The library uses two coordinate systems:
| System | Description | Use Case | |--------|-------------|----------| | Viewport | Pixel coordinates relative to current zoom | Rendering on screen | | Scaled | Normalized (0-1) coordinates relative to page | Storage & retrieval |
// Converting between systems
const { viewportToScaled } = useHighlightContainerContext();
// Save position (viewport → scaled)
const scaledPosition = viewportToScaled(boundingRect);
// Highlights are automatically converted to viewport when renderingCustomization
Custom Highlight Interface
interface MyHighlight extends Highlight {
category: string;
comment?: string;
author?: string;
}
// Use the generic type
const { highlight } = useHighlightContainerContext<MyHighlight>();Custom Styling
// Via props
<TextHighlight
highlight={highlight}
style={{ background: categoryColors[highlight.category] }}
/>
// Via CSS classes
.TextHighlight { }
.AreaHighlight { }
.FreetextHighlight { }
.ImageHighlight { }
.DrawingHighlight { }Tips and Popups
import { MonitoredHighlightContainer } from "react-pdf-highlighter-plus";
<MonitoredHighlightContainer
highlightTip={{
position: highlight.position,
content: <MyPopup highlight={highlight} />,
}}
>
<TextHighlight highlight={highlight} />
</MonitoredHighlightContainer>Running Locally
git clone https://github.com/QuocVietHa08/react-pdf-highlighter-plus.git
cd react-pdf-highlighter-plus
npm install
npm run devAPI Reference
See the full API Reference for detailed documentation on all components and types.
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
For bugs, please open an issue with clear reproduction steps.
License
MIT
Credits
Originally forked from react-pdf-highlighter with significant architectural changes including context-based APIs, zoom support, freetext/image/drawing highlights, and PDF export functionality.
