Appearance
Getting Started with ContinueJS
Welcome to ContinueJS! If you've ever spent 15 minutes filling out a job application, support ticket, or multi-step wizard only for your laptop battery to die or your browser tab to accidentally refresh — you already understand why ContinueJS exists.
ContinueJS is a continuity engine for the web. It automatically saves temporary user state into the browser's IndexedDB storage and restores it seamlessly when the user returns.
💡 The Problem We Solve
Traditional web forms are ephemeral. Unless your server is constantly auto-saving every keystroke (which introduces latency, privacy concerns, and database bloat), user work lives entirely in fragile DOM inputs.
When a tab closes or refreshes:
- ❌ Unsaved text in textareas is wiped.
- ❌ Radio buttons and checkboxes reset.
- ❌ Multi-step wizard state is lost.
- ❌ Selected dropdown options reset to defaults.
How ContinueJS Changes This
With ContinueJS, your web application gains a local persistence layer in seconds:
[ User Inputs Data ] ──> ( Debounced Observer ) ──> [ IndexedDB Local Store ]
│
( User Returns )
│
[ Restored Form ] <── ( Web Component Banner ) <──────────┘🚀 5-Minute Quick Start
Let's see how easy it is to add ContinueJS to a standard HTML form.
1. Install Core Package
bash
npm install @continuejs/core @continuejs/ui2. Attach to a Form
In your JavaScript or TypeScript code:
typescript
import { attach } from '@continuejs/core';
import '@continuejs/ui'; // Registers <continuejs-banner> and <continuejs-modal>
// 1. Attach ContinueJS to your form
const { draft } = attach({
target: document.querySelector('#contact-form'),
id: 'contact-form-draft',
options: {
retention: '7d', // Keep draft for 7 days
debounceMs: 300, // Debounce autosave by 300ms
excludeFields: ['captcha'], // Don't save security captchas
},
});
// 2. Check if a draft exists from a previous session
async function checkForSavedProgress() {
const hasDraft = await draft.hasDraft();
if (hasDraft) {
const lastSaved = await draft.lastSaved();
// Display the recovery banner
const banner = document.createElement('continuejs-banner');
banner.setAttribute('last-saved', String(lastSaved));
banner.setAttribute('message', 'We found unsaved progress from your previous visit!');
banner.addEventListener('continuejs-restore', async () => {
await draft.restore(); // Automatically fills out all form fields!
});
banner.addEventListener('continuejs-discard', async () => {
await draft.delete(); // Clears local IndexedDB draft
});
document.querySelector('#form-container').prepend(banner);
}
}
checkForSavedProgress();3. Clear Draft on Successful Submission
Once the user successfully submits the form to your backend API, clear the draft so they start fresh next time:
typescript
document.querySelector('#contact-form').addEventListener('submit', async (e) => {
e.preventDefault();
await sendDataToBackend();
// Clean up saved local draft
await draft.delete();
alert('Form submitted successfully!');
});🎯 What Makes ContinueJS Unique?
- Local-First & Privacy-Preserving: No accounts, no cloud servers, no tracking scripts. Data never leaves the browser.
- Framework Agnostic: Works natively in Vanilla JS, React, Vue, Svelte, Angular, Solid, or Web Components.
- Password Security: Password fields and sensitive input types are automatically ignored.
- Zero Dependencies: Lightweight TypeScript codebase under 10 KB gzipped.
