Appearance
Troubleshooting & Migration Guide
A practical reference for handling edge cases, Content Security Policy (CSP) rules, Incognito browsing modes, SPA hydration, and migration strategies.
🔍 Frequently Encountered Issues
1. Incognito / Private Browsing Mode Restrictions
Symptom: In strict private browsing modes (e.g. Firefox Private Browsing or Chrome Incognito with block 3rd-party data enabled), window.indexedDB may throw security errors or operate in ephemeral memory mode.
Solution: ContinueJS features built-in fallback routing via StoreManager. If IndexedDB access is denied by browser security policies, ContinueJS seamlessly falls back to SessionStorageBackend or MemoryBackend without crashing your application.
typescript
// Explicitly define fallbacks if desired:
const draft = createDraft({
id: 'user-form',
storage: 'indexeddb', // Will automatically fall back if unavailable
});2. Content Security Policy (CSP) Headers
Symptom: Web Components or Web Crypto API calls are blocked by strict server headers.
Required CSP Directive Adjustments:
- Script Directives: Ensure
'unsafe-inline'or appropriate nonce/hash is permitted for script tags. - Style Directives: Shadow DOM styles in
<continuejs-banner>and<continuejs-modal>requirestyle-src 'unsafe-inline'. - Worker / Storage Directives: IndexedDB runs on the main thread and requires no special worker directive.
Example header:
http
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' https://esm.sh;3. SPA Hydration & Dynamic Input Registration (React, Vue, Svelte)
Symptom: Form input values reset during client-side hydration or when dynamic inputs are added after page mount.
Solution:
- Ensure
attach()oruseDraftis called insideuseEffect(React),onMounted(Vue 3), oronMount(Svelte). FormObserveruses aMutationObserverunder the hood to automatically detect new input elements added dynamically to the DOM tree.
🔄 Backward Compatibility & Migration
If you are upgrading an older site that used legacy draft scripts or earlier API syntax, ContinueJS v1.0.0 will not break your existing codebase.
Permissive attach() Signatures
You can pass string CSS selectors, DOM elements directly, or standard config objects:
typescript
// All of these syntax patterns work identically in ContinueJS v1.0.0:
// 1. String CSS selector
attach('#contact-form');
// 2. Direct DOM Element with custom ID
attach(document.querySelector('form'), 'contact-draft');
// 3. Modern config object
attach({
target: document.querySelector('#contact-form'),
id: 'contact-draft',
});Legacy Helper Aliases
ContinueJS exports backward-compatible function aliases for legacy codebases:
typescript
import { autoSave, saveForm, restoreForm, Form } from '@continuejs/core';
// Older legacy script calls automatically map to ContinueJS v1.0.0:
autoSave('#my-form');
saveForm(document.querySelector('form'));