Persistence

Learn how to create persisted stores and keep track of state changes between page navigations.

Spruce provides an API for persisting stores between page navigations. This means that your global state can be updated on one page, saved to local storage and that updated data can then be used on another page.

This is really useful for retaining the state of particular components between page navigations.

Creating a persisted store

To create a persisted store, you need to pass a third argument to the Spruce.store() method. This argument should be a boolean (true or false).

Spruce.store('colorScheme', 'light', true)

When this piece of state is mutated, it will be automatically persisted to local storage and fetched on the next page load.

<button x-data @click="$store.colorScheme = 'dark'">Use Dark Mode</button>

When this <button> is clicked, the value of colorScheme is set to 'dark' and will be set to that on the next page navigation too.

Some browsers disable access to local storage when in private browsing mode, meaning persisted stores do not work.

Adding methods to persisted stores

Persisted stores can have methods, just like regular stores. The methods are merged in to the persisted data object after retrieval.

Spruce.store('user', {
name: 'Ryan Chandler',
getFirstName() {
return this.name.split(' ')[0]
}
}, true)

After making a change to the store and navigating to a different page that also uses this store, you will still be able to call the $store.user.getFirstName() method.

Only top-level methods are merged into the persisted object. This means any nested methods will not be available on the persisted store.

Accepted data types

Persisted stores only support data types that are JSON serialisable.

Using a custom driver

The persistence API provided by Spruce is driver-based. This means you can swap out the way persisted stores are handled with your own custom implementation.

To change the driver, use the Spruce.persistUsing() method.

Spruce.persistUsing(window.sessionStorage)

The example above swaps out the default localStorage driver with the sessionStorage one. Both of these objects implement a getItem(key) and setItem(key, value) method, meaning they are compatible.

If you wish to use a completely bespoke solution, you can provide your own object. This object must also implement the getItem(key) and setItem(key, value) methods. These methods will be called by Spruce when initialising persisted stores and saving changed data.

Spruce.persistUsing({
getItem(key) {
return db.get(key)
},
setItem(key, value) {
db.set(key, value)
}
})

Be sure to set / change the driver before creating or declaring any persisted stores. Spruce will not re-persist stores after their initial load, or when the driver is changed.