# How should a web app handle the same draft being edited in two browser tabs?

> Use server-enforced revision checks for draft saves, layer browser-tab warnings on top, and add merge UX only when field-level merges are genuinely safe.

Canonical URL: https://www.devobs.io/articles/qa-multiple-tabs-edit-same-draft/
By: Ines Costa
Published: 2023-06-11T05:53:32.786Z
Updated: 2026-09-06T08:31:04.426Z
Section: Architecture

Treat two-tab editing as a data-concurrency problem, not a notification problem. For a personal draft, the default pattern is: every save carries the draft revision the tab last read, and the server only accepts the write if that revision still matches. If it does not, return a conflict and show the user what changed. Use browser cross-tab messaging only as an advisory warning, because tab messages do not enforce ordering or prevent stale writes. The HTTP tool for this is a conditional write such as [`If-Match` in RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-if-match).

## What policy should you choose?

For a personal draft, pick one of three policies deliberately.

**Single active editor** is best when the draft is simple and losing edits would be unacceptable, but merge UX would be overkill. When tab B opens the same draft, show it as read-only or ask to take over editing. This reduces confusion, but only works if your server still enforces a write condition; otherwise a sleeping old tab can wake up and overwrite newer work.

**Conflict detection on save** is the right default. It keeps both tabs usable, allows local autosave, and only interrupts the user when the second save would overwrite a newer version. This is usually enough for notes, invoices, and profile drafts.

**Deliberate merge UX** is worth building only when users commonly make independent edits to separable fields and the cost of interruption is high. It is a product decision, not a free technical upgrade.

## Where is the real ordering boundary?

The enforced boundary is the save itself. A preflight “has this changed?” check is not enough, because another tab can save after the check and before your write. The server must compare the client’s expected revision and perform the update as one guarded operation.

In HTTP terms, a client can send the last known entity tag with [`If-Match` in RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-if-match). If the tag no longer matches, the server rejects the request instead of silently accepting a stale overwrite. That is the part that resolves the race.

## What are browser tab messages good for?

Use cross-tab messaging to improve UX, not correctness. The web platform supports broadcasting to other browsing contexts, but even the standard focuses on message delivery and security checks, not conflict resolution. The [HTML Standard section on broadcasting to other browsing contexts](https://html.spec.whatwg.org/multipage/web-messaging.html#broadcasting-to-other-browsing-contexts) and its messaging guidance make this a coordination channel, not a lock manager.

Good uses:
- “This draft is open in another tab.”
- “Newer saved version detected; reload or review changes.”
- “Autosave paused because this tab is stale.”

Do not treat those messages as authoritative. Tabs can be backgrounded, suspended, crashed, or miss a warning.

## What does this look like in a real draft?

Example: two tabs edit invoice draft `INV-42` at revision 7.

- Tab A changes the billing address and saves with revision 7.
- Server accepts, writes revision 8.
- Tab B changes the internal note and tries to save with revision 7.
- Server rejects with conflict.
- UI shows: “This invoice changed in another tab from revision 7 to 8.” Then offer:
  - reload latest draft,
  - copy B’s unsaved note into the latest version,
  - or review a side-by-side diff.

If your fields are independent and normalized, you may auto-merge specific changes such as `internalNote` when the server can prove that field was untouched since revision 7. Do not auto-merge rich text, reordered lists, or derived totals unless you already have a domain-specific merge model.

## Follow-up: What if a tab sleeps?

Assume it will wake up stale. On resume, refetch metadata or attempt the next autosave with the old revision and handle the conflict normally. Do not trust an in-memory “I am leader” flag.

## Follow-up: When is automatic merging safe?

Only when the data model gives you independent fields with clear ownership and no hidden coupling. If one field affects validation, pricing, or generated content elsewhere, surface a conflict instead.

Next step: add a revision column or ETag to your draft resource, reject stale saves at write time, and then layer tab-to-tab warnings on top.

Reviewed: 2026-09-05

## Source references

- <https://www.rfc-editor.org/rfc/rfc9110.html#name-if-match>
- <https://html.spec.whatwg.org/multipage/web-messaging.html#broadcasting-to-other-browsing-contexts>
