Persist form drafts across sessions
Use persist on Form to auto-save in-progress input to localStorage so unsaved drafts survive a page reload.
A blog post editor can take a long time to fill in. If the user accidentally refreshes the page or their browser crashes, all their unsaved text is gone. Setting persist="true" on the form silently snapshots the current field values to localStorage on every change and restores them on the next visit.
<App>
<Button
variant="outlined"
label="Reset the temporary form data"
onClick="clearLocalStorage()"
/>
<Form
id="postEditor"
persist="true"
storageKey="blog-post-draft"
data="{{ title: '', category: 'general', body: '' }}"
dataAfterSubmit="clear"
completedNotificationMessage="Post published — draft cleared!"
onSubmit="(data) => delay(300)"
saveLabel="Publish"
>
<TextBox label="Title" bindTo="title" required="true" />
<Select
label="Category"
bindTo="category"
data="{['general', 'tech', 'design']}"
/>
<TextArea label="Body" bindTo="body" required="true" />
</Form>
</App>Try these steps:
- Type in some data into the form.
- Click the “Reset the App” button in the top-right corner of the example header. This action refreshes the example page while keeping the previously typed data.
- Submit the form. The successful submission clears the temporary data.
- Type some data again.
- Click the “Reset the temporary form data” button. It will clear the persisted temporary data.
- Click the “Reset the App” button again. This action refreshes the example page — this time, the data will be empty.
<App>
<Button
variant="outlined"
label="Reset the temporary form data"
onClick="clearLocalStorage()"
/>
<Form
id="postEditor"
persist="true"
storageKey="blog-post-draft"
data="{{ title: '', category: 'general', body: '' }}"
dataAfterSubmit="clear"
completedNotificationMessage="Post published — draft cleared!"
onSubmit="(data) => delay(300)"
saveLabel="Publish"
>
<TextBox label="Title" bindTo="title" required="true" />
<Select
label="Category"
bindTo="category"
data="{['general', 'tech', 'design']}"
/>
<TextArea label="Body" bindTo="body" required="true" />
</Form>
</App>Try these steps:
- Type in some data into the form.
- Click the “Reset the App” button in the top-right corner of the example header. This action refreshes the example page while keeping the previously typed data.
- Submit the form. The successful submission clears the temporary data.
- Type some data again.
- Click the “Reset the temporary form data” button. It will clear the persisted temporary data.
- Click the “Reset the App” button again. This action refreshes the example page — this time, the data will be empty.
Key points
persist="true" saves on every keystroke: As soon as the user types in any field, the form's current state is written to localStorage under the storageKey. On the next page load, the form restores those values automatically — the user continues exactly where they left off:
<Form persist="true" storageKey="invoice-draft" data="{{ ...empty initial values... }}">
…
</Form>storageKey gives the localStorage entry a stable name: If omitted, the form uses its id attribute. If neither is set, it defaults to "form-data" — which risks collisions when multiple forms use persistence on the same origin. Always set an explicit storageKey or id:
<Form id="postEditor" persist="true" storageKey="blog-post-draft">
<!-- storageKey wins over id when both are set -->
</Form>The draft is cleared on successful submit: After onSubmit completes without error, the framework clears the localStorage entry automatically. No manual cleanup is needed. Combine with dataAfterSubmit="clear" to also empty the visible fields:
<Form persist="true" storageKey="blog-post-draft" dataAfterSubmit="clear">
<!-- submitted → field values cleared AND localStorage entry erased -->
</Form>doNotPersistFields excludes sensitive fields: Pass an array of bindTo names to keep those fields out of localStorage while still including them in the submission:
<Form persist="true" doNotPersistFields="{['cardNumber', 'cvv']}">
<TextBox bindTo="cardNumber" label="Card number" />
<TextBox bindTo="cvv" label="CVV" />
<!-- cardNumber and cvv are submitted normally but never written to localStorage -->
</Form>keepOnCancel controls draft retention after cancel: By default, pressing Cancel clears the persisted draft. Set keepOnCancel="true" to preserve the draft even when the user cancels — useful for editors where Cancel closes a modal but the user might re-open it later:
<Form persist="true" storageKey="post-draft" keepOnCancel="true">See also
- Form component —
persist,storageKey,doNotPersistFields,keepOnCancel - Reset a form after submission —
dataAfterSubmitoptions