Consider a notice editor where a reviewer selects one passage for discussion. The author should see that passage highlighted while the actual saved HTML remains untouched. A separate review note can explain the question without adding a red error marker to valid text.
Create one collection for this review feature
For an existing Monaco editor and its attached model:
const reviewHighlights = editor.createDecorationsCollection();
function showReviewPassage(range) {
reviewHighlights.set([{
range,
options: {
inlineClassName: 'review-passage',
stickiness:
monaco.editor.TrackedRangeStickiness
.NeverGrowsWhenTypingAtEdges
}
}]);
}
Define the class in the host application's stylesheet:
.monaco-editor .review-passage {
background: #fff0b3;
border-bottom: 2px solid #806200;
}
Choose a palette with readable text under the application's active themes. The decoration options distinguish inline classes from whole-line, glyph-margin, and overview-ruler decorations. For a short passage, start with the inline range the reader actually needs.
With a fictional one-line source <p>Collect the kit at reception.</p>, this highlights “reception”:
showReviewPassage(new monaco.Range(1, 23, 1, 32));
Monaco uses one-based columns and an exclusive end position. Compute real review ranges from the actual model or stored reference; this fixed range belongs only to the illustrated source. If text is inserted before the passage, inspect reviewHighlights.getRange(0) for its current tracked position.
Track position without pretending to understand meaning
Monaco maps decoration ranges through text edits. stickiness controls whether typing at range edges expands the decoration. The chosen setting keeps new edge text outside the range. It does not determine whether a rewritten sentence still answers a reviewer's question.
Keep the comment's actual identity and resolution state in application data. If the referenced wording is removed or substantially rewritten, ask the review workflow to resolve or reattach that comment. A surviving range is positional evidence, not approval of the new sentence.
Use set() when moving this single active review highlight. Repeated append() calls would retain old ranges and can make one selected question appear to concern several passages. Other independent features should own their own collections so clearing a review selection does not remove search results or another feature's visual state.
Keep diagnostics and source separate
For an actual application error, use model markers, including an owner, severity, and explanatory message. A yellow passage highlight has no such validation contract. Likewise, reading the editor DOM to save highlighted HTML risks capturing interface elements; save the model's source instead.
When closing the review feature, call:
reviewHighlights.clear();
Bind the collection's lifetime to the editor and intended document. On document changes, clear or rebuild the review state from that document's references; do not reuse another record's hard-coded columns.
In the actual application, highlight the passage, insert text before it, inspect the tracked range, and clear it. Compare the model value before and after highlighting alone: it should be identical. End the review by saving the author's source and the comment state through their separate storage paths.