data-autosave

Automatically save form drafts to localStorage as the user types. Restores on page reload with a toast notification. Clears on submit or reset.

Overview

The data-autosave attribute automatically persists form data to localStorage as the user types. If the page is accidentally closed or refreshed, the draft is restored on the next visit with a toast notification. The draft is cleared when the form is submitted or reset.

<form data-autosave="contact-form"> <input name="name" placeholder="Name"> <textarea name="message" placeholder="Message"></textarea> <button type="submit">Send</button> </form>

How It Works

Add data-autosave to any <form> element with a unique key as the value. The init script:

  1. Attaches delegated input and change event listeners on the form
  2. On every field change, debounces for 500ms then serializes all named fields to a JSON object
  3. Saves the object to localStorage with the key vb-autosave:{key} and a timestamp
  4. On page load, checks for a non-expired draft (24-hour expiry)
  5. If a draft exists, restores field values and fires input events so other enhancements update
  6. Shows a "Draft restored" toast notification via toast-msg if available
  7. Sets data-autosave-init to prevent double-binding

Password fields (type="password") and file inputs (type="file") are always skipped — sensitive data and file references are never stored.

Attributes

Attribute Value Description
data-autosave string (required) A unique storage key for this form. Used as part of the localStorage key: vb-autosave:{key}.
data-autosave-init boolean Set automatically to prevent double-binding. Do not set manually.

Storage Format

The draft is stored as a JSON object in localStorage. Each named field in the form becomes a key-value pair. A _ts timestamp is included for expiry checking.

// Storage key format localStorage.getItem('vb-autosave:contact-form'); // Stored value is a JSON object of field name/value pairs // { // "name": "Jane", // "message": "Hello...", // "_ts": 1700000000000 // }
Detail Value
Key format vb-autosave:{key}
Debounce 500ms after last input
Expiry 24 hours from last save
Skipped types password, file

Multiple Forms

Each form on a page must have a unique data-autosave key. The key is used directly in the localStorage key, so collisions between forms on different pages are avoided by using descriptive names.

<!-- Each form needs a unique key --> <form data-autosave="signup-form"> <input name="email" type="email" placeholder="Email"> <input name="username" placeholder="Username"> <button type="submit">Sign Up</button> </form> <form data-autosave="feedback-form"> <textarea name="feedback" placeholder="Your feedback"></textarea> <button type="submit">Submit</button> </form>

Checkboxes and Radios

Checkbox and radio inputs are handled correctly during both save and restore:

  • Checkboxes — stored as "on" when checked, "" when unchecked. On restore, the checked property is set accordingly.
  • Radio buttons — only the checked radio's value is stored for the group name. On restore, the matching radio is checked.
<form data-autosave="preferences"> <fieldset> <legend>Notifications</legend> <label> <input type="checkbox" name="email-notify" value="yes"> Email notifications </label> <label> <input type="checkbox" name="sms-notify" value="yes"> SMS notifications </label> </fieldset> <fieldset> <legend>Theme</legend> <label> <input type="radio" name="theme" value="light"> Light </label> <label> <input type="radio" name="theme" value="dark"> Dark </label> </fieldset> <button type="submit">Save</button> </form>

With Other Enhancements

When a draft is restored, input events are fired on each restored field. This ensures other Vanilla Breeze enhancements that listen for input events — such as data-count, data-grow, and data-show-when — update correctly.

<form data-autosave="registration" class="stacked"> <form-field> <label for="reg-email">Email</label> <input type="email" id="reg-email" name="email" required> </form-field> <form-field> <label for="reg-name">Full Name</label> <input type="text" id="reg-name" name="fullname" required> <small slot="help">As it appears on your ID.</small> </form-field> <form-field> <label for="reg-bio">Bio</label> <textarea id="reg-bio" name="bio" data-count="200" data-grow></textarea> </form-field> <button type="submit">Register</button> </form>

Toast Notification

When a draft is restored, a toast notification is displayed if toast-msg is available on the page. The toast uses the following configuration:

  • Message: "Draft restored"
  • Variant: info
  • Duration: 3000ms (auto-dismisses)

If toast-msg is not present, the draft is still restored silently without a notification.

Clear Behavior

The autosave draft is automatically cleared in two scenarios:

  • Form submit — the draft is removed from localStorage when the form is submitted
  • Form reset — the draft is removed when the form is reset via a reset button or form.reset()
// Drafts are cleared automatically on submit and reset form.addEventListener('submit', () => { // autosave data is cleared before the submit handler runs }); // You can also clear manually localStorage.removeItem('vb-autosave:contact-form');

Styling

The autosave attribute itself has no visual output. The only visible indicator is the toast notification on restore, which inherits styles from toast-msg.

/* The toast notification uses toast-msg if available */ /* Customize the restore notification via toast-msg styles */ toast-msg::part(toast) { --toast-bg: var(--color-surface-raised); --toast-color: var(--color-text); }

All behavior is gated on data-autosave-init. Without JavaScript, the form works normally — data simply is not persisted to localStorage.

Accessibility

  • The "Draft restored" toast notification is announced by screen readers via toast-msg's accessible live region
  • Restored form state preserves the user's previous work, reducing frustration from accidental navigation
  • No visual layout changes occur during restore — fields are populated in place
  • Firing input events on restore ensures dependent enhancements (character counts, conditional fields) are in the correct state for assistive technology
  • Password and file fields are excluded from storage for security — users are not given a false sense of persistence for sensitive data
  • Without JavaScript, the form works as a standard HTML form — progressive enhancement