Session Persistence
By default, session data lives only in memory and is lost on page reload. Enable persistence to automatically save and restore sessions via IndexedDB.
Pass persist: true with a contentId to the constructor:
const tracker = new WriteTrack({ target: textarea, contentId: 'post_draft_42', // Required with persist persist: true,});
// Wait for any prior session data to load from IndexedDBawait tracker.ready;
// start() will auto-resume the prior session if one existstracker.start();When a session is resumed, all previously captured events are restored and new events are appended. The sessionId stays the same across resumes, and a segment counter in the metadata tracks how many times the session was resumed.
How It Works
Section titled “How It Works”- Storage key: Sessions are stored by
contentId:fieldId, wherefieldIdis derived fromdata-writetrack-field,id, ornameon the target element. - Page unload: On
beforeunload, the current session is synchronously saved tolocalStorageas a fallback (IndexedDB transactions don’t survive page unload). On the next load, this is promoted back to IndexedDB. readypromise: Resolves when IndexedDB has loaded any prior session. Alwaysawait tracker.readybefore callingstart()when persistence is enabled.stop(): Saves the session to IndexedDB. After callingstop(),readyresolves again once the save completes.- Cleanup: Call
clearPersistedData()to remove the stored session for this field (e.g., after successful form submission).
Multi-Field Forms
Section titled “Multi-Field Forms”Each field gets its own persisted session, keyed by contentId:fieldId. Give each tracked element a distinct id or data-writetrack-field attribute:
const trackers = ['#title', '#body', '#summary'].map((sel) => { const el = document.querySelector<HTMLTextAreaElement>(sel)!; const t = new WriteTrack({ target: el, contentId: 'post_42', persist: true }); return t;});
await Promise.all(trackers.map((t) => t.ready));trackers.forEach((t) => t.start());Cleanup After Submission
Section titled “Cleanup After Submission”After the user submits the form, clear persisted data so the next visit starts fresh:
form.addEventListener('submit', async (e) => { e.preventDefault(); const data = tracker.getData(); tracker.stop(); await tracker.ready; // wait for final save await tracker.clearPersistedData(); // remove from IndexedDB
await fetch('/api/submit', { method: 'POST', body: JSON.stringify(data) });});Managing Persisted Sessions
Section titled “Managing Persisted Sessions”For multi-document applications, use the static methods to list and delete persisted sessions without creating a WriteTrack instance:
// List all persisted sessionsconst sessions = await WriteTrack.listPersistedSessions();// [{ contentId: 'doc_1', fieldId: 'default', keystrokeCount: 42, ... }]
// Delete all sessions for a document (e.g., when user deletes it)await WriteTrack.deletePersistedSession('doc_1');
// Delete a specific field's sessionawait WriteTrack.deletePersistedSession('doc_1', 'body');Related
Section titled “Related”persistoption — Constructor option referencereadypromise — Await persistence loadingclearPersistedData()— Remove stored sessionslistPersistedSessions()— List all stored sessionsdeletePersistedSession()— Delete sessions by contentId- Privacy & Security — How persistence affects data storage