Ace HTML editor: keep each file's text and undo history in its own session

Ace edits HTML source when its session uses ace/mode/html. For a tabbed editor, create a separate EditSession for each file and switch with editor.setSession(). Replacing one shared session's value whenever a tab changes can discard the document state you intended to retain. Ace embedding and session guide

Imagine editing arrival.html and parking.html. Change the arrival page to say “Check in at the west desk,” switch to parking, and return. The arrival correction should still be there, and Undo should affect the arrival document rather than the other file.

Give the editor a visible container

Ace's official guide requires a container with usable dimensions. For example:

<div id="page-source" style="height:360px"></div>

Load Ace and its HTML mode through the deployment method appropriate to your application. If modes or workers load dynamically, keep their asset paths and versions consistent. This guide assumes the existing ace browser API and the HTML mode are available; the following fragment does not install those assets.

Create one session per file

const editor = ace.edit('page-source');
const sessions = new Map([
  ['arrival.html', ace.createEditSession(
    '<h1>Arrival</h1>\n<p>Check in at reception.</p>',
    'ace/mode/html'
  )],
  ['parking.html', ace.createEditSession(
    '<h1>Parking</h1>\n<p>Use the south lot.</p>',
    'ace/mode/html'
  )]
]);

for (const session of sessions.values()) {
  session.setUseWrapMode(true);
  session.setTabSize(2);
  session.setUseSoftTabs(true);
}

let activeFile = 'arrival.html';
editor.setSession(sessions.get(activeFile));

function openFile(name) {
  const session = sessions.get(name);
  if (!session) throw new Error('Unknown file');
  editor.setSession(session);
  activeFile = name;
  editor.focus();
}

Connect openFile() to your application's existing file-tab controls. The session holds document-specific editor state, including its undo manager. The containing application still manages tab labels, unsaved markers, authorization, and persistence.

Avoid calling session.setValue() during an ordinary tab switch. Ace documents that operation as setting the value and resetting undo history. Use it when a deliberate load or replacement should establish a new document baseline, after resolving unsaved changes.

Save the file the action actually refers to

Capture the active identity and source together when Save is invoked:

function captureActiveFile() {
  const name = activeFile;
  const session = sessions.get(name);
  return { name, html: session.getValue() };
}

const payload = captureActiveFile();
// Send payload through the application's authorized save operation.

That captures a payload; it does not save a file. If the request finishes after the user switches tabs, apply its acknowledgement to payload.name. Do not mark whichever tab happens to be active at response time as saved. A later edit in the same session also needs its own unsaved state.

For a Save All command, capture each intended session separately. Reading only editor.getValue() obtains the current editor's text, not the text of every open file.

Check switching before adding preview features

Use the two fictional files to test your actual application:

  1. Change arrival to “west desk,” switch to parking, and confirm parking still says “south lot.”
  2. Return to arrival and invoke Undo. Confirm the arrival change is reversed without altering parking.
  3. Reapply the correction, save arrival, switch tabs while the request is pending, and check which tab receives the acknowledgement.
  4. Reopen the saved arrival record in a fresh editing context and read the west-desk instruction.

Syntax highlighting is separate from rendering. Ace does not turn its HTML mode into a webpage preview or a sanitizer. If the host panel changes size and Ace's view does not follow, use the documented editor.resize() after the layout change.

The Monaco integration guide covers models and worker setup in a different embedded editor. For this Ace workflow, finish with each file's session, undo behavior, and saved source checked independently before connecting a reader preview.

Keep reading