Annotations in an e-book reader let you mark up specific passages — highlights, underlines, sticky notes — and return to them later. In foliate-js, annotations are stored externally as EPUB CFI strings and rendered on top of the page content using an SVG overlay. The library never persists annotations itself; it fires events that give your code the chance to draw whatever you like over a given text range.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/johnfactotum/foliate-js/llms.txt
Use this file to discover all available pages before exploring further.
How annotations work
When you callview.addAnnotation(), foliate-js resolves the CFI to the correct section, finds the on-screen range, and fires a draw-annotation event. Your event handler calls the provided draw callback with a draw function and any options. The draw function delegates to an Overlayer instance, which maintains an SVG element positioned exactly over the page content.
The Overlayer class is the low-level primitive. <foliate-view> creates one overlayer per loaded section automatically and passes it through the renderer’s create-overlayer event.
Adding and removing annotations
addAnnotation is async because resolving the CFI may require loading section data. If the annotation’s section is not currently rendered, foliate-js stores it and applies it the next time that section loads.
deleteAnnotation(annotation) is a convenience wrapper that calls addAnnotation(annotation, true) internally. It removes the drawn element from the SVG overlay for that section.
Drawing annotations with the draw-annotation event
When a non-search annotation is added, <foliate-view> emits a draw-annotation event. The event detail contains:
draw(func, opts)— call this to register the draw function for this annotationannotation— the original annotation object you passed toaddAnnotationdoc— the sectionDocumentobjectrange— the resolved DOMRange
draw once per draw-annotation event. The first argument is the draw function; the second is options passed through to it. foliate-js calls your draw function with (rects, options) where rects is the DOMRectList from range.getClientRects().
Built-in draw functions
Overlayer ships five static draw functions. All accept a DOMRectList as the first argument and an options object as the second.
Overlayer.highlight(rects, options)
Draws filled rectangles behind the text. Opacity and blend mode are controlled via CSS custom properties so they can be changed without redrawing.
color— fill color string (default'red')
--overlayer-highlight-opacity (default 0.3) and blend mode via --overlayer-highlight-blend-mode (default normal).
Overlayer.underline(rects, options)
Draws a thin line below each text rect. Supports vertical writing modes.
color— line color (default'red')width— stroke width in pixels (default2)writingMode— set to'vertical-rl'or'vertical-lr'to place the line on the right edge instead of the bottom
Overlayer.strikethrough(rects, options)
Draws a line through the middle of each text rect. Accepts the same options as underline.
Overlayer.squiggly(rects, options)
Draws a wavy line below each text rect (or to the right in vertical writing). Accepts the same options as underline.
Overlayer.outline(rects, options)
Draws a rounded rectangle border around each text rect. Used internally for search result highlights.
color— stroke color (default'red')width— stroke width in pixels (default3)radius— corner radius in pixels (default3)
Responding to annotation clicks
When the user clicks on a drawn annotation,<foliate-view> fires a show-annotation event:
value is the same CFI string from the original annotation object. index is the section index, and range is the DOM Range of the annotation. Use these to position a popover or open an edit dialog.
The overlayer does not have event listeners by default. Hit testing is done by comparing click coordinates against the stored client rects of each annotation’s range, not the SVG element itself.
The create-overlay event
<foliate-view> also fires a create-overlay event when an overlayer is first created for a section:
<foliate-view> handles replaying pending annotations automatically. It is primarily useful when you need to know that a specific section’s overlay is initialized.
The Overlayer class interface
If you need lower-level access — for example, when building a custom renderer — you can work with Overlayer directly:
The SVG element. The renderer inserts, sizes, and positions it automatically when you use
<foliate-view>.Adds an annotation.
key can be any value used as a Map key (typically the CFI string). range is a DOM Range or a function that receives the root node and returns a Range. draw is the draw function. If a previous entry with the same key exists, it is removed first.Removes the annotation with the given key and its SVG element.
Redraws all annotations by recalculating client rects and calling each draw function again. Called by the renderer after layout changes (page turns, resize).
Returns
[key, range] for the topmost annotation at the given viewport coordinates, or an empty array if nothing was hit. Hit testing uses the stored client rects, not the SVG element, so it works even if pointer-events: none is set.Custom draw functions
You can provide any function that accepts(rects, options) and returns an SVG element:
<svg> root.