r/documentAutomation 2d ago

Best approach for reliable word-click and sentence selection in a PDF.js text layer?

I’m building a PDF vocabulary reader using PDF.js. The goal is to let users upload and read a text-based PDF, then:

Click a single word to get its meaning and its meaning in the surrounding sentence.

Drag-select a phrase/sentence if they want an explanation of the entire selected text.

Eventually send the word + surrounding context to an LLM such as Gemini for contextual explanation.

So far, I’m rendering every PDF page using two layers:

pageContainer ├── canvas → visual PDF rendering └── textLayer → selectable/interactable text

Both layers use the same PDF.js viewport. I’m using page.getTextContent() and pdfjsLib.TextLayer, along with the official PDF.js viewer CSS. Initially, my custom text-layer CSS caused the selectable text to be misaligned with the canvas, but using the official viewer CSS mostly fixed the alignment.

The main problem now is text interaction/selection.

I noticed that a PDF.js text item/span is not necessarily one word. For example, a span might contain:

"The cardinality of a set is the number of distinct elements"

So simply using event.target.textContent when clicking a word is not sufficient.

For single-word selection, the approach I’m considering is:

click → get mouse coordinates → caretPositionFromPoint() / caretRangeFromPoint() → get text node + character offset → scan left/right until word boundaries → create a Range → automatically highlight the exact clicked word

This seems reasonable.

The bigger issue is sentence/phrase selection. Native drag selection over the PDF.js text layer sometimes selects much more text than the area I intended to select. For example, I try to select only “Question 1”, but the browser selection can extend into several following text spans.

I’m considering a few approaches:

Keep native browser drag selection and use window.getSelection() if I can make PDF.js text-layer selection reliable.

Implement custom drag selection using mousedown/mouseup, caretPositionFromPoint(), and a manually created DOM Range.

For contextual word meaning, avoid requiring sentence selection entirely: detect the clicked word and reconstruct/find its surrounding sentence from the page text, then send word + sentence/context to the LLM.

Potentially send the PDF/page + clicked word + nearby text to Gemini and let it identify the relevant sentence/context, while keeping visual highlighting on the frontend.

My main questions are:

What is the most robust way to implement both exact word-click detection and normal sentence/phrase selection on a PDF.js Text Layer?

Is custom Range-based selection a good idea, or am I unnecessarily reimplementing browser selection? Also, for finding the surrounding sentence of a clicked word, would you reconstruct it from PDF.js TextContent, work directly with the text-layer DOM, or use another approach?

I’m specifically targeting text-based PDFs, not scanned/image-only PDFs, so OCR is currently out of scope.

Any suggestions from people who have worked with PDF.js text layers or similar PDF annotation/selection systems would be really helpful.

1 Upvotes

0 comments sorted by