Save configuration to localstorage

I wrote a utility that lets notebook authors give readers the power to save view values to localstorage to return to later:

I don’t know if there’s prior art on this sort of thing, but I’d be curious to see if so! Very interested if anyone actually ends up using this.

While writing it, I also got curious if there’s a way to uniquely identify a notebook. I’m currently admonishing notebook authors to ensure that they use keys that will be unique across all their notebooks for the storable, but it would be nice if there were a way to guarantee that without making the notebook author pass in a key at all.

2 Likes

You can get the URL of the notebook as a prefix for keys.

Yeah, there is prior art though the API is slightly different, I went for a standalone view you need to manually bind

I am very to see another person ‘get’ the power of back writing for composability

2 Likes

Since Tom skipped over it: You can get the parent path with

new URL(document.baseURI).pathname

Note that using this path as prefix may make previously stored storage data unavailable in other views (e.g. compare or history).

If you want to use the notebook’s owner name as prefix, you can instead use:

document.location.hostname.split('.', 2)[0]
2 Likes

Thanks @mootari! I’ve updated the notebook to make the key optional (defaulting to the notebook path) and added some docs with the appropriate warnings. By default it will key off the notebook URL.

I think in this case notebook makes more sense than author since sharing stored data between notebooks is likely uncommon and localstorage is already scoped to author.static.observableusercontent.com

1 Like

I had the idea before I even noticed the back-writing functionality and I was worried it was going to be very complicated and hacky to implement. What a delight it was to discover you had already thought of what I needed!

Right, forgot about that, sorry.

A while back I also started Storage / Fabian Iwand | Observable, but I haven’t even gotten around to finalizing the interfaces yet.

2 Likes

A while back I also started Storage / Fabian Iwand / Observable , but I haven’t even gotten around to finalizing the interfaces yet.

I feel like the answer should be a backwritable ‘view’, you choose your storage engine by choosing which engine you Input.bind to your control.

My two examples so far urlQueryFieldView: Non-invasive URL field persistence / Tom Larkworthy | Observable localStorageView: Non-invasive local persistance / Tom Larkworthy | Observable While it is nice to hide the Input.bind, I think it is a mistake because view-literal supports fine grained binding, so you can persist different parts of the UI control state with different storage backends if you let the user do the actual the binding. When you get to auto-save you need more control over saving and loading so you will outgrow input.bind and then having the view as a standalone thing provides an escape hatch for more control.

I have discussed this in the section “views-as-services” of Scaling User Interface Development / Tom Larkworthy | Observable