Monaco diff editor: keep the original and modified models separate

Create a Monaco diff editor with monaco.editor.createDiffEditor(), then attach an object containing original and modified text models through setModel(). Read the modified model when saving the reviewed result. The diff editor compares source text; it does not render an HTML page or resolve concurrent edits against a shared ancestor. Monaco diff editor API

An original room-booking notice has two changes under review: the collection desk moves from the foyer to reception, and the closing time moves from 5 p.m. to 4 p.m. A reviewer needs to keep the new desk while correcting the closing time. Saving the original pane after that review would silently discard the chosen result.

Attach two models with explicit roles

Give an existing host element a usable height, for example <div id="notice-diff" style="height:480px"></div>. In an application whose Monaco package, styles, and workers are already configured:

import * as monaco from 'monaco-editor';

const original = monaco.editor.createModel(
  '<p>Collect at the foyer. Close at 5 p.m.</p>',
  'html',
  monaco.Uri.parse('inmemory://notice/approved.html')
);
const modified = monaco.editor.createModel(
  '<p>Collect at reception. Close at 4 p.m.</p>',
  'html',
  monaco.Uri.parse('inmemory://notice/proposed.html')
);
const diff = monaco.editor.createDiffEditor(
  document.getElementById('notice-diff'),
  {
    automaticLayout: true,
    originalEditable: false,
    readOnly: false,
    renderSideBySide: true,
    originalAriaLabel: 'Approved notice source',
    modifiedAriaLabel: 'Proposed notice source'
  }
);
diff.setModel({ original, modified });

These are build-source imports, not a complete standalone HTML file. Use distinct model URIs for distinct open documents. The Monaco HTML setup guide covers the worker and container setup that this fragment assumes.

originalEditable: false keeps the baseline pane from ordinary editing. readOnly: false allows the proposed side to be edited. Neither setting authorizes server writes: the application still decides which revision a user may replace. Label both roles visibly around the editor, in addition to their accessibility labels.

Save the current modified value

After the reviewer changes only the closing time back to 5 p.m.:

const reviewedHtml = modified.getValue();

The intended value is:

<p>Collect at reception. Close at 5 p.m.</p>

Pass that value, the notice identity, and the approved revision identifier to the application's existing review or save operation. getValue() retrieves text from memory. It does not confirm that storage accepted the change. If the approved version has changed since the comparison opened, the application needs to detect that stale baseline before recording an approval.

Keep editing and saved state separate in the interface. A reviewer who edits the modified pane should see unsaved work until the actual operation succeeds. Do not capture modified.getValue() only during initial mounting and reuse that earlier string when Save is clicked.

Choose a narrow-panel layout deliberately

The diff options include renderSideBySide, useInlineViewWhenSpaceIsLimited, and renderSideBySideInlineBreakpoint. When enabled, the inline fallback uses one combined view below the configured breakpoint. Check the values supported by the installed release and the page's actual container width. Diff construction options

An inline layout changes presentation, not which model is original or modified. Read the room-booking fixture in both layouts. The reviewer should still be able to identify the retained reception change and the corrected time. Test the accessible diff viewer and the application's labels if the review must work without relying on red and green decorations.

Line highlights show textual differences. They cannot establish that the final notice has valid HTML, a usable mobile layout, or the intended meaning. Render the chosen source in its intended reader environment separately before approving its presentation.

Dispose only the resources this review owns

For this example, the review creates both models and owns them exclusively. When the review is permanently closed, after handling unsaved work:

diff.dispose();
original.dispose();
modified.dispose();

A model shared by another view needs a shared lifetime policy. Closing one comparison must not destroy a document that remains open elsewhere.

In the running integration, edit the modified time, confirm the original string remains unchanged, and inspect the value sent by Save. Reopen the saved notice and read both the desk and time. The CodeMirror merge guide explains a different package's directional revert controls; Monaco's two model references should remain explicit throughout this review.

Keep reading