Save Wix Form progress with Local Storage

I was inspired by this question from @hans about temporarily saving form data to allow users to continue editing it later on.

It’s also useful for when users lose their form input from refreshing or closing the page.

This guide will cover:

  • Automatically saving form values in the browser
  • Only store the fields we want
  • Wait until users stop typing before saving
  • Expire the saved data after 24 hours
  • Clear saved data when the form is submitted

Notes

This demo uses the new Wix Forms

This topic should serve as a reference. Please conduct your own research before using it in a production environment.


:hammer_and_wrench: Setup

Step 1: Give your form an ID

Open either the Wix Studio, or Wix Editor, and:

  1. Enable code
  2. Select your form
  3. Give it an ID - for example myForm
    Screenshot 2025-06-02 at 10.40.30

Step 2: Add this code to your page

Paste the following code into the page’s code panel.

import { local } from "@wix/site-storage";

// Used to version the stored data
const FORM_VERSION = "v1";

// Fields you do NOT want to save (e.g. Personal Information)
const FIELDS_TO_EXCLUDE = ["firstName", "email"];

// Expire stored form data after 24 hours
const TTL = 1000 * 60 * 60 * 24;

function debounce(fn, delay) {
  let timer;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

function excludeFields(data) {
  return Object.fromEntries(
    Object.entries(data).filter(([key]) => !FIELDS_TO_EXCLUDE.includes(key))
  );
}

$w.onReady(async function () {
  // Step 1: Try to load saved data
  const data = await local.getItem("formSubmission");
  let parsed;

  try {
    parsed = JSON.parse(data);
  } catch (e) {
    parsed = null;
  }

  // Step 2: If saved data exists AND is valid AND not expired → restore it
  if (
    parsed &&
    parsed.version === FORM_VERSION &&
    parsed.timestamp &&
    parsed.timestamp > Date.now() - TTL
  ) {
    $w("#myForm").setFieldValues(parsed.values);
  }

  // Step 3: Save form values — but wait until the user stops typing
  const saveForm = debounce(async (newValues) => {
    const filtered = excludeFields(newValues);
    await local.setItem("formSubmission", JSON.stringify({
      version: FORM_VERSION,
      timestamp: Date.now(),
      values: filtered
    }));
  }, 500);

  $w("#myForm").onFieldValueChange(saveForm);

  // Step 4: Once form is submitted, remove saved data
  $w("#myForm").onSubmit(() => {
    local.removeItem("formSubmission");
  });
});

:magnifying_glass_tilted_left: What Each Part Does

local.getItem / setItem / removeItem

We use the @wix/site-storage module to store the form values locally in the user’s browser - so they persist even if they refresh the page.


FORM_VERSION

If you ever change your form structure, older saved data might become incompatible.

Adding a FORM_VERSION helps prevent issues:

parsed.version === FORM_VERSION

If the version doesn’t match, we ignore the saved data.


FIELDS_TO_EXCLUDE

Sometimes your form includes information you don’t want saved in the browser. For example:

  • Names
  • Email addresses

You probably don’t want to save or restore those.

So we filter them out:

function excludeFields(data) {
  return Object.fromEntries(
    Object.entries(data).filter(([key]) => !FIELDS_TO_EXCLUDE.includes(key))
  );
}

TTL (Time To Live)

We don’t want form data lingering forever.

This line ensures the data is only restored if it’s less than 24 hours old:

parsed.timestamp > Date.now() - TTL

If it’s expired, it’s ignored.


debounce

Forms can trigger onFieldValueChange every time you type - which would hammer storage and slow things down.

So we debounce the save:

const saveForm = debounce(async (newValues) => { ... }, 500);

This means it waits until the user stops typing for 500ms before saving.


onSubmit

Once the user submits the form, we don’t want to keep their old data around. So we clear it:

$w("#myForm").onSubmit(() => {
  local.removeItem("formSubmission");
});

Done!

That’s it - your form now:

  • Auto-saves values to the browser
  • Skips fields you don’t want
  • Only restores if recent
  • Clears after submit
  • And won’t flood storage with every keystroke

Happy building :sparkles:

2 Likes