Skip to main content

Build AI Citation in WebViewer

AI Citation connects an LLM answer to exact locations in the PDF so users can verify where each claim comes from. The core API is text.locateSource(), which maps quoted source text to page coordinates you can highlight in the viewer.

Why this matters

In document-heavy workflows (legal, finance, compliance, research), users need traceability, not just fluent answers. AI Citation solves that by:
  • taking LLM-provided source quotes
  • locating those quotes in the document text layer
  • rendering highlight rects directly in WebViewer
No additional LLM call is needed for the locate/highlight step.

Prerequisites

  • A loaded PDF in WebViewer
  • LLM output that includes quote citations (not plain prose only)
  • High-quality Markdown/text extracted from the same PDF (for quote grounding)
text.locateSource() is designed for high-quality model output. Avoid passing noisy, manually typed snippets.

Flow

Your app: PDF -> Markdown -> LLM answer with quote citations MuPDF WebViewer APIs: text.locateSource() -> viewer.highlight() + viewer.scrollTo()
  • You implement: PDF-to-Markdown pipeline, prompt/response contract for quoted citations, and when citation actions should run (for example on answer render, hover, or click).
  • WebViewer provides: quote-to-coordinate mapping via text.locateSource(), plus rendering/navigation APIs (viewer.highlight() and viewer.scrollTo()).
Use a structured response where each paragraph carries one or more citations with verbatim quote text.
The important field for AI Citation is quote. That quote is what you pass to text.locateSource().

Example

This example resolves all quotes from an answer, highlights every matched rect, and scrolls to the first resolved page.

Production checklist

  • Cache quote -> locateSource result to remove duplicate lookups.
  • Handle unresolved quotes gracefully (skip or show “source not found”).
  • Batch highlight rects in one viewer.highlight() call when possible.
  • Optionally use pageRange in text.locateSource({ text, pageRange }) for faster scoped lookup.
  • Keep citation click targets in the UI so users can jump between answer and source pages.

Next steps