The URL as State Manager

One of the most common pain points cited by developers in the annual StateOfJS survey (now open! take it!) is “state management”. Usually accessing state from various parts of the app, but also sending it over the wire for server rendering or for syncing it with other users (and, at scale, performantly updating relevant parts of the app when state changes).

For small usecases, a mechanism for that exists: the humble URL! specifically, the humble URLSearchParam.

When you serialize state to your URL, you can simply copy and paste your url bar to a coworker, who can then navigate directly to what you are seeing, with every text field and filter set exactly how you had it. It’s basically an ultra flexible “direct link” for your app state. It’s a magical experience when implemented well, and horribly frustrating when some parts of state are serialized but others are not.

Aside: this insight isnt just limited to the URLSearchParam; any frontend router essentially takes over the entire URL as a state manager - when you navigate to a new page, the URL updates clientside and the router updates its internal state accordingly. Just for some weird reason, routers typically stop at parsing/setting the search/query param when it is incredibly useful for sharing/serializing app state.

I suspect the reason that more people don’t use URLSearchParams for state management is because the API is pretty low level:

  • Mostly oriented around reading rather than setting
  • no allowance for type safety
  • hard to subscribe to changes to keep things up to date

Fortunately, https://github.com/paoloricciuti/sveltekit-search-params now handles that as a single Svelte Store, making it dead easy to set and get searchParams, define default values, and trusting that everything else from type safety to SSR-friendliness is all done for you.

The basic API we want:

<script lang="ts">
    import { queryParameters } from "sveltekit-search-params";

    const store = queryParameters();
</script>

<pre>
    {JSON.stringify($store, null, 2)}
</pre>
The count is {$store.count}
<input bind:value={$store.count} type="number"/>

sveltekit-search-params was implemented in swyxkit in sw-yx#140/. You can see the amount of custom, hacky, untested code it replaces. Thanks to @paoloricciuti for the PR!


    Tagged in: #url #state #svelte #stores

    Leave a reaction if you liked this post! 🧡
    Loading comments...

    Subscribe to the newsletter

    Get emails from me about Lorem ipsum dolor sit, amet consectetur adipisicing elit. Libero, ducimus..

    5,432 subscribers including my Mom – 123 issues

    Latest Posts

    Search and see all posts