Persist Vuex State between Page Reloads with LocalStorage and IndexedDB

Wortharead, a blogs aggregator app that assembled the largest DB of 20,000+ Substack newsletters, uses Vuex to store and manage the shared state of all Vue components, such as the articles in the Today Feed, feeds followed by the user, and articles r…


This content originally appeared on DEV Community and was authored by Xiaoyang Liu

image

Wortharead, a blogs aggregator app that assembled the largest DB of 20,000+ Substack newsletters, uses Vuex to store and manage the shared state of all Vue components, such as the articles in the Today Feed, feeds followed by the user, and articles recommended in the Explore section. However, when using Vuex out-of-the-box, the Vuex state is lost and reset to default when the page is refreshed, causing unnecessary network requests.

This article will talk about how we initially solved this problem using LocalStorage and later how and why we migrated to IndexedDB (hint: LocalStorage only lets you store 5MB of data).

LocalStorage

image

To persist and rehydrate the Vuex state between page reloads, we initially chose to save the state to LocalStorage after each mutation and read the data from it when the page is reloaded. The vuex-persist plugin implements this functionality and provides extensive TypeScript type declaration.

npm install --save vuex-persist

To use it, install the plugin and import VuexPersistence from vuex-persist. Set storage to window.localStorage and register vuexLocal.plugin as a Vuex plugin. Refresh the page and then the state will be saved to LocalStorage.

const vuexLocal = new VuexPersistence({
  storage: window.localStorage,
});
Vue.use(Vuex);
const store = new Vuex.Store<State>({
  state: { ... },
  mutations: { ... },
  actions: { ... },
  plugins: [vuexLocal.plugin],
});
export default store;

IndexedDB

image

After several iterations, Wortharead decided to save article content storage in Vuex to ensure that users can read cached articles offline. Since LocalStorage is limited to about 5MB, the large amount of article data quickly exhausted the storage quota, causing unpredictable errors. Therefore, we chose to migrate the persisted state to IndexedDB.

npm install --save localforage

localForage implements a simple, localStorage-like API for IndexedDB, which is compatible with vuex-persist. Import localForage from the package and set storage to localForage. Since localForage storage is asynchronous, set the asyncStorage option to true.

import Vue from 'vue';
import Vuex from 'vuex';
import VuexPersistence from 'vuex-persist';
import localForage from 'localforage';
const vuexLocal = new VuexPersistence({
  storage: localForage,
  asyncStorage: true,
});
Vue.use(Vuex);
const store = new Vuex.Store<State>({
  state: { ... },
  mutations: { ... },
  actions: { ... },
  plugins: [vuexLocal.plugin],
});
export default store;

When we first attempted to use this library, it seemed to work: data was being successfully stored and the app worked. However, on a page refresh, the data disappeared. We worried that the migration to IndexedDB may not be so easy. After some exploration though, we figured out the issue.

Since localForage is promise-based storage, the state will not be immediately restored into Vuex. It will go into the event loop and will finish when the JS thread is empty, which could invoke a delay of few seconds. vuex-persist injected a restored property to the store object, which contains a Promise that will be resolved after the state is restored. The beforeEach() hook in vue-router could cause the app to wait for vuex-persist to restore the state before taking any further actions.

import Vue from 'vue';
import Router from 'vue-router';
import { store } from '@/store'; // the location of Vuex store

Vue.use(Router);
const router = new Router({
  // define the routes
});

router.beforeEach(async (to, from, next) => {
  await store.restored;
  next();
});

export default router;


This content originally appeared on DEV Community and was authored by Xiaoyang Liu


Print Share Comment Cite Upload Translate Updates
APA

Xiaoyang Liu | Sciencx (2021-07-25T01:53:31+00:00) Persist Vuex State between Page Reloads with LocalStorage and IndexedDB. Retrieved from https://www.scien.cx/2021/07/25/persist-vuex-state-between-page-reloads-with-localstorage-and-indexeddb/

MLA
" » Persist Vuex State between Page Reloads with LocalStorage and IndexedDB." Xiaoyang Liu | Sciencx - Sunday July 25, 2021, https://www.scien.cx/2021/07/25/persist-vuex-state-between-page-reloads-with-localstorage-and-indexeddb/
HARVARD
Xiaoyang Liu | Sciencx Sunday July 25, 2021 » Persist Vuex State between Page Reloads with LocalStorage and IndexedDB., viewed ,<https://www.scien.cx/2021/07/25/persist-vuex-state-between-page-reloads-with-localstorage-and-indexeddb/>
VANCOUVER
Xiaoyang Liu | Sciencx - » Persist Vuex State between Page Reloads with LocalStorage and IndexedDB. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/07/25/persist-vuex-state-between-page-reloads-with-localstorage-and-indexeddb/
CHICAGO
" » Persist Vuex State between Page Reloads with LocalStorage and IndexedDB." Xiaoyang Liu | Sciencx - Accessed . https://www.scien.cx/2021/07/25/persist-vuex-state-between-page-reloads-with-localstorage-and-indexeddb/
IEEE
" » Persist Vuex State between Page Reloads with LocalStorage and IndexedDB." Xiaoyang Liu | Sciencx [Online]. Available: https://www.scien.cx/2021/07/25/persist-vuex-state-between-page-reloads-with-localstorage-and-indexeddb/. [Accessed: ]
rf:citation
» Persist Vuex State between Page Reloads with LocalStorage and IndexedDB | Xiaoyang Liu | Sciencx | https://www.scien.cx/2021/07/25/persist-vuex-state-between-page-reloads-with-localstorage-and-indexeddb/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.