APP-71Recommended
Keep a local copy that syncs on reconnect
For documents people edit offline, keep a copy in the browser's IndexedDB, apply each edit to it first and send the missing changes on reconnect. Show whether the copy is in step with the server.
How to do it
Local-first means the screen never waits for the network. With a CRDT, each side says which changes it has and receives only the missing ones. Browser storage can be cleared, as Expect browser storage to fail or be cleared says, so the server copy stays the one you back up. Tell people they are offline as Say when the network is gone describes. Native apps queue changes as Queue offline changes and resolve conflicts on the server says.
Examples
TypeScript example
const doc = new Y.Doc();
const local = new IndexeddbPersistence(`doc-${documentId}`, doc);
await local.whenSynced;
const remote = new WebsocketProvider('wss://collab.example.com', `doc-${documentId}`, doc);
remote.on('sync', (inStep: boolean) => showSaveState(inStep ? 'Saved' : 'Saving'));
Python example
from playwright.sync_api import expect
def test_offline_edit_survives_reload(page, context):
page.goto("https://staging.example.com/docs/42")
context.set_offline(True)
page.get_by_role("textbox", name="Document").press_sequentially("Order 40 boxes")
page.reload()
expect(page.get_by_role("textbox", name="Document")).to_contain_text("Order 40 boxes")
context.set_offline(False)
expect(page.get_by_role("status")).to_have_text("Saved")
assert "Order 40 boxes" in documents.text("42")
How to check
A browser test goes offline, types in a document and reloads the page while still offline. The text is still there. Back online, the server copy holds the text and the page shows "Saved".
Sources
Related rules
- APP-60 Expect browser storage to fail or be cleared in Web app interface
- APP-52 Say when the network is gone in Web app interface
- MOB-26 Queue offline changes and resolve conflicts on the server in Mobile apps
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/app-ui/live-collaboration/local-first-sync">Agent Wranglers web app interface playbook</a>. In code you write, add a comment next to it with the same link.