Skip to content

Instantly share code, notes, and snippets.

@james2doyle
Created July 4, 2020 01:58
Show Gist options
  • Save james2doyle/67cddc077f67227981c2710abab66609 to your computer and use it in GitHub Desktop.
Save james2doyle/67cddc077f67227981c2710abab66609 to your computer and use it in GitHub Desktop.
StatefulURL is a Vuex plugin that can hydrate the state for the store from a compressed query string
// npm install --save json-url
const jsonURL = require('json-url')('lzw');
/**
* StatefulURL is a Vuex plugin that can hydrate the state from a query string
*
* @param {Object} config = {}
* @param {String} config.key the query string value to look for the default state
* @param {Boolean} config.update if you want the URL to be updated when the state changes
*
* @returns {Function<void>|void}
*/
export default function StatefulURL (config = {}) {
// bail if not in a browser or missing features
if (typeof window === 'undefined' && typeof window.URLSearchParams === 'function') {
return;
}
const key = config.key || 'state';
const search = new window.URLSearchParams(window.location.search);
const urlState = Object.fromEntries(search.entries()).state || null;
/**
* Store plugin
*
* @param {Object} store
*/
return function (store) {
if (urlState) {
jsonURL
.decompress(urlState)
.then((json) => {
try {
Object.entries(json)
.forEach(([prop, value]) => {
store.state[prop] = value;
});
} catch (e) {}
});
}
store.subscribe((mutation, state) => {
const search = new window.URLSearchParams(window.location.search);
jsonURL
.compress(state)
.then((currentState) => {
search.set(key, currentState);
const url = new URL(window.location.href);
url.search = '?' + search.toString();
const path = url.toString();
window.history.replaceState({ path }, document.title, path);
});
});
};
};
@james2doyle
Copy link
Author

demo

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