← Back to all Resources

Saving and Retrieving User Input with Local Storage

Custom code
Forms
Marketing

This technique demonstrates how to capture form data in real-time using localStorage, then retrieve and display it dynamically on a redirected page such as a thank-you or confirmation screen.

The approach works by listening to user input events on the form page, saving each input's name and value to localStorage as the user types. Once the form is submitted and the user is redirected, custom code on the destination page retrieves this saved data and displays it in designated page elements. For the retrieval to work reliably, the input names and the IDs of the destination page elements must align precisely.

This client-side pattern is lightweight, requires no backend setup, and can be a valuable enhancement for form-driven Webflow projects.

Custom code

Example of code that can be used to save user input selection to local storage and retrieve it on the relevant page.

Main page where the form is.

// Get the form element by its ID
const form = document.getElementById("form");

// Add an event listener to the form for any input event
form.addEventListener("input", function (event) {
  // Try to get the existing form data from localStorage, or use an empty object if none exists
  let formData = JSON.parse(localStorage.getItem("formData")) || {};
  // Update the formData object with the new value from the input that triggered the event
  formData[event.target.name] = event.target.value;
  // Save the updated formData object back to localStorage as a JSON string
  localStorage.setItem("formData", JSON.stringify(formData));
});

Page user is redirected to i.e., /thank-you page.

// Retrieve saved form data from localStorage
const formData = JSON.parse(localStorage.getItem("formData"));

if (formData) {
  // Iterate over each key in the formData object
  Object.keys(formData).forEach(function (key) {
    // Find the element with the corresponding id
    const el = document.getElementById(key);
    if (el) {
      // Set the element's text content to the saved value
      el.textContent = formData[key];
    }
  });
}

Cloneable

Inspect and clone this project to investigate/test as needed: https://webflow.com/made-in-webflow/website/form-saved-values.

Additional Thoughts

Prevent Visual Flashing with a Loading State

  • Avoid unstyled content: Elements meant to be populated via custom code may flash on screen before data is injected, which can look broken or confusing.
  • Recommended action: Initially hide these elements with CSS or add a loading class until all values are retrieved and applied.

Input & ID Alignment

  • Consistency is critical: For the data to populate correctly on the redirected page, each input’s name attribute on the form page must match the id of the element where the value will be displayed on the thank-you page.
  • Avoid mismatches: A typo or mismatch between name="firstName" and id="firstname" will silently fail.

Storage Limits & Scope

  • Storage size: localStorage has a limit (~5–10MB depending on the browser), which is more than enough for simple forms, but not ideal for large uploads or file inputs.
  • Same origin policy: The thank-you page must be on the same domain (and protocol) as the form page for localStorage access to work.

Real-Time Persistence

  • Live updating: Because the script listens to the input event, data is saved as the user types. This helps with session recovery if the page reloads or crashes.
  • Edge case: For checkboxes, radios, and selects, verify that event.target.value reflects the correct state—especially for unchecked or default options.

Data Cleanup

  • Persistence beyond need: localStorage is persistent across sessions. If you don’t manually clear it, saved form data might be visible to the next visitor.
  • Alternatively, use sessionStorage if you want the data to disappear once the tab or browser is closed.

Fallback for Missing Data

  • Handle missing or incomplete entries: Not all sessions will have data (e.g. user visits thank-you page directly or disables storage).
  • Recommended action: Provide default placeholders or logic to gracefully handle empty/missing values rather than showing blank or broken layout elements.

Related resources

Retrieving UTM Parameters and Adding Hidden Inputs to Forms

Captures UTM parameters as hidden form inputs for campaign tracking via form submissions.
Developer
Video
Custom code
Forms
Marketing

Using an iframe on the page

Performance and accessibility considerations when using iframes
Developer
Article
Accessibility
Performance
Custom code
Security

Creating your own middleware

A guide to creating middleware to protect your API keys when making front-end calls in Webflow
Developer
Github
Custom code
API

Connecting Webflow forms to other services

Considerations of Webflow forms and connectivity options for sending form submission data to other services
Marketer
Article
Forms

Dialog element for modals and popups

Build more accessible pop up elements by using the dialog element with custom elements in Webflow
Developer
Nugget
Accessibility
Custom code

Custom code workflows

Methods for working with custom code in Webflow
Developer
Article
Custom code

Dynamic no-index tag for CMS template pages

Apply no-index tags to specific CMS items
Marketer
Video
CMS
Custom code
SEO

Link to specific tab using the tabs element

Low-code solution to link to specific tab with the native Webflow tab element
Developer
Video
Custom code

Adding social share links to collection template page

Low-code method of adding social media share links to CMS pages
Developer
Video
CMS
Custom code

Distribute CMS content across multiple sites from the main Webflow site

Add content to one Webflow site and have it distributed to all Webflow sites
Developer
Video
CMS
Custom code