Remix.run Logo
least 4 hours ago

Sure. I'm not speaking about preserving the full history stack in the URL, just storing state. Apologies in advance if my explanation for what I mean is something you already understand.

This can be as simple as having a single checkbox with a checked/unchecked state.

when you load the webpage, the javascript can pull in the url parameters with URLSearchParams (https://developer.mozilla.org/en-US/docs/Web/API/URLSearchPa...). If the url parameter you set is set to 'on' then the checkbox, which is by default unchecked, can be set to on.

You have your checkbox:

    <input type="checkbox" id="check">
And then you have your javascript:

    const check = document.getElementById('check');
  
    // get state of checkbox from URL parameter
    check.checked = new URLSearchParams(location.search).get('state') === 'on';
    
    // add event listener to call history api to alter the URL state.
    check.onchange = () => { history.replaceState(null, '', check.checked ? '?state=on' : '?state=off'); };

The history.replaceState() replaces the URL in your history with the one including the URL parameter, so if a user were to bookmark it, it would store that and reload it when they revisit the webpage.

If I used history.pushState(), each time I clicked on the checkbox, a new item would be added to the stack. for a checkbox this is almost certainly a bad idea because your browser history is going to be polluted pretty quickly if you happen to click it multiple times.

pushState can be useful when it matches the user expectations, though, like if it is an SPA and the user clicks on an internal link to another section of the site, they'd expect to be able to go back to the previous page, even though we're still on the same actual html page.

So you would not be preserving the entire history stack. You can sort of do this by encoding state changes into another url parameter, but the behavior isn't entirely consistent between browsers. It also does require, as far as I know, an explicit action from the user for it to actually affect their navigation. So a website couldn't just add 1000 entries to the user's history on load without some explicit interaction on the web page.

Once the user interacts, though, it does seem like it opens up a lot of opportunity to abuse it, intentionally or not. You can asynchronously push thousands of entries into the browser history without blocking interactivity of the site. you can even continue to push state to the URL from other inputs while doing so.