Jump to the Next Highlight Keyword Programmatically

Scenario
Section titled “Scenario”When the PDF document is loaded, the system programmatically highlights two keywords:
- Case-sensitive:
"JavaScript" - Whole word with regular expression:
"language"or"languages"
The selected keywords should appear more than once and be located across different pages. Each highlighted keyword uses a different color.
The system should allow users to view and navigate to where the keywords are found in the PDF document.
What to Use
Section titled “What to Use”The useHighlightContext provides a function to highlight text in a PDF without any manual text selection.
Here are the functions we’re using for this example
| Name | Objective |
|---|---|
highlight | Set initial highlight text once the document is loaded |
highlightMatches | Provide the highlight matches information eg. page number, highlighted texts position |
matchHighlight | The MatchHighlight interface provides the values of each highlight match. |
The usePaginationContext provides access to pagination-related state and functions for navigating through pages in a PDF document:
| Name | Objective |
|---|---|
goToPage | Update the focused page and scroll to that page |
import { useEffect } from "react";import { RPProvider, RPPages, RPTheme, useHighlightContext, RPLayout, RPHorizontalBar, usePaginationContext,} from "@pdf-viewer/react";
const HighlightWords = () => { const { highlight, highlightMatches } = useHighlightContext(); const { goToPage } = usePaginationContext();
// Automatically highlight keywords when document loads useEffect(() => { highlight([ { keyword: "compilation technique", highlightColor: "rgba(255, 179, 0, 0.5)" }, { keyword: "JavaScript", highlightColor: "rgba(0, 255, 0, 0.5)", options: { matchCase: true, wholeWords: true } }, { keyword: /\blanguage(s)?\b/, highlightColor: "rgba(255, 0, 255, 0.5)" }, // RegExp: match "language" or "languages" ]); }, []);
// Group highlights by keyword and page const grouped = Object.values( highlightMatches.reduce((acc, item) => { const key = `${item.keyword}_${item.page}`; if (!acc[key]) acc[key] = { str: item.str, page: item.page, items: [] }; acc[key].items.push(item); return acc; }, {}) );
return ( <ol> {grouped.map((h) => ( <li key={`${h.str}_${h.page}`} style={{ fontSize: "12px", marginTop: "12px" }}> <span style={{ marginRight: "5px" }}>{h.str}</span> <button style={{ border: "1px solid red", padding: "4px 5px" }} onClick={() => goToPage(h.page)}> go to page {h.page} </button> </li> ))} </ol> );};
// Left sidebar displaying highlight listconst MyLeftSidebar = () => ( <div style={{ padding: "8px", overflow: "auto" }}> <HighlightWords /> </div>);
// Main PDF Viewer componentconst AppPdfViewer = () => ( <RPTheme> <RPProvider src="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"> <RPLayout toolbar={{ topbar: { component: <RPHorizontalBar /> }, leftSidebar: { component: <MyLeftSidebar /> } }}> <RPPages /> </RPLayout> </RPProvider> </RPTheme>);
export default AppPdfViewer;import { useEffect } from "react";import { RPProvider, RPPages, RPTheme, useHighlightContext, RPLayout, RPHorizontalBar, usePaginationContext, MatchHighlight} from "@pdf-viewer/react";
interface GroupedHighlight { str: string; page: number; items: MatchHighlight[];}
const HighlightWords = () => { const { highlight, highlightMatches } = useHighlightContext(); const { goToPage } = usePaginationContext(); // Automatically highlight keywords when document loads useEffect(() => { highlight([ { keyword: "compilation technique", highlightColor: "rgba(255, 179, 0, 0.5)" }, { keyword: "JavaScript", highlightColor: "rgba(0, 255, 0, 0.5)", options: { matchCase: true, wholeWords: true } }, { keyword: /\blanguage(s)?\b/, highlightColor: "rgba(255, 0, 255, 0.5)" }, // RegExp: match "language" or "languages" ]); }, []);
const grouped = Object.values( highlightMatches.reduce((acc: Record<string, GroupedHighlight>, item: MatchHighlight) => { const key = `${item.keyword}_${item.page}`; if (!acc[key]) acc[key] = { str: item.str, page: item.page, items: [] }; acc[key].items.push(item); return acc; }, {} as Record<string, GroupedHighlight>) );
return ( <ol> {grouped.map((h: GroupedHighlight) => ( <li key={`${h.str}_${h.page}`} style={{ fontSize: "12px", marginTop: "12px" }}> <span style={{ marginRight: "5px" }}>{h.str}</span> <button style={{ border: "1px solid red", padding: "4px 5px" }} onClick={() => goToPage(h.page)}> go to page {h.page} </button> </li> ))} </ol> );};
// Left sidebar displaying highlight listconst MyLeftSidebar = () => ( <div style={{ padding: "8px", overflow: "auto" }}> <HighlightWords /> </div>);
// Main PDF Viewer componentconst AppPdfViewer = () => ( <RPTheme> <RPProvider src="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"> <RPLayout toolbar={{ topbar: { component: <RPHorizontalBar /> }, leftSidebar: { component: <MyLeftSidebar /> } }}> <RPPages /> </RPLayout> </RPProvider> </RPTheme>);
export default AppPdfViewer;For live demo and complete code sample, check out the demo on Stackblitz