Skip to content

Experiment: Preserve customer support form info between refreshes - #3363

Open
lvachon1 wants to merge 3 commits into
mainfrom
lev/exp/form_keeper
Open

Experiment: Preserve customer support form info between refreshes#3363
lvachon1 wants to merge 3 commits into
mainfrom
lev/exp/form_keeper

Conversation

@lvachon1

Copy link
Copy Markdown
Contributor

Scope

Asana Ticket: 🙋 Investigate customer support form reloading issues

Implementation

As part of the above investigation I have written a stop-gap/band-aid fix that will make the experience less frustrating for users that experience page refreshes.

This JS code saves the state of the form in localStorage when any field is changed. If the page is refreshed/loaded and the cached form data is <24h old, it will fill out the form and put the user back where they were.

Unfortunately it is not allowed to set file inputs from JS, the user will have to manually re-select them.

The Captcha will/should not be affected either. Those clicks actually expire after a few minutes.

Screenshots

Screen.Recording.2026-07-27.at.11.47.27.AM.mov

How to test

http://localhost:4001/customer-support

Play with the form, put it into various states, refresh and see if it behaves as expected. Drop-downs, text fields, hidden/shown sections and checkboxes should all resume their previous state upon refresh. If a user is typing when the form crashes/refreshes they should lose at most 1 character.

Moving Forward

It appears that our DotcomWeb controllers import Phoenix.LiveView and that establishes a websocket connection and hearbeats. However, on this page at least, no other data is being sent that way. I think we should see if we can remove that requirement and see if the lack of a websocket connection will help.

lvachon1 added 3 commits July 24, 2026 13:19
…eloads. This is a bandaid until we can properly fix this page.
… modify the form get a chance to fire when loading from localStorage
@lvachon1
lvachon1 requested a review from a team as a code owner July 27, 2026 15:51
@lvachon1
lvachon1 requested a review from jlucytan July 27, 2026 15:51

@joshlarson joshlarson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great change! I left a few comments/suggestions. The one thing that's holding me back from approving is the invalid-JSON thing... I know it's unlikely, but rule 1 about getting data from users is to assume that it's probably invalid or wrong in some way 😅

Comment thread assets/js/support-form.js

if(!cacheString || cacheString.length<10){return;}//No data, bail
const cacheData = JSON.parse(cacheString)
if(cacheData.time < Date.now()-86400000){return;}//Data is too old, bail

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion (non-blocking): Some quick back-of-the-envelop math tells me that this is one day. How would you feel about pulling this out to a constant, like so, to make it super explicit?

ONE_DAY_MS = 1000 * 60 * 60 * 24

Comment thread assets/js/support-form.js
const cacheString = localStorage.getItem("support-form-cache")

if(!cacheString || cacheString.length<10){return;}//No data, bail
const cacheData = JSON.parse(cacheString)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue (blocking): If cacheString somehow winds up becoming an invalid JSON, then that causes the javascript to crash, which prevents future attempts to save state (and I think it also prevents form submission). This error is unrecoverable unless the user clears their browser data.

Another issue (non-blocking): If the time field somehow goes missing, but the JSON is otherwise valid, then cacheData.time will become undefined, and in its infinite wisdom, Javascript has decided that all numerical comparisons with undefined should evaluate to false, which means that we'll keep our undefined-time old submission around forever. I'm thinking if cacheData.time is undefined, we probably also want to bail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants