JAVASCRIPT

Create a Reusable useLocalStorage Composable

Build a custom Vue 3 Composition API composable, `useLocalStorage`, to effortlessly persist and retrieve reactive state in the browser's local storage.

// src/composables/useLocalStorage.js
import { ref, watch, onMounted, onUnmounted } from 'vue';

export function useLocalStorage(key, defaultValue) {
  const value = ref(defaultValue);

  const read = () => {
    try {
      const storedValue = localStorage.getItem(key);
      return storedValue ? JSON.parse(storedValue) : defaultValue;
    } catch (error) {
      console.error(`Error reading localStorage key "${key}":`, error);
      return defaultValue;
    }
  };

  const write = (newValue) => {
    try {
      localStorage.setItem(key, JSON.stringify(newValue));
    } catch (error) {
      console.error(`Error writing localStorage key "${key}":`, error);
    }
  };

  // Initialize value from localStorage on mount
  onMounted(() => {
    value.value = read();
  });

  // Watch for changes to 'value' and update localStorage
  watch(value, (newValue) => {
    write(newValue);
  }, { deep: true }); // Use deep watch for objects/arrays

  // Optional: Handle localStorage events from other tabs/windows
  const handleStorageChange = (event) => {
    if (event.key === key) {
      value.value = read();
    }
  };

  onMounted(() => {
    window.addEventListener('storage', handleStorageChange);
  });

  onUnmounted(() => {
    window.removeEventListener('storage', handleStorageChange);
  });

  return value;
}

// src/App.vue
<template>
  <div>
    <h1>useLocalStorage Composable Example</h1>
    <p>Edit the input to persist the value in local storage. Open a new tab with this app to see the synced value!</p>
    <label>
      Your Name:
      <input type="text" v-model="userName" />
    </label>
    <p>Stored Name: {{ userName }}</p>

    <hr />

    <label>
      Preferences:
      <input type="checkbox" v-model="userPreferences.darkMode" /> Dark Mode
      <input type="checkbox" v-model="userPreferences.notifications" /> Notifications
    </label>
    <pre>{{ userPreferences }}</pre>

    <button @click="resetName">Reset Name</button>
  </div>
</template>

<script setup>
import { useLocalStorage } from './composables/useLocalStorage'; // Adjust path

// Storing a simple string
const userName = useLocalStorage('appUserName', 'Guest');

// Storing an object (requires deep watch in composable)
const userPreferences = useLocalStorage('appUserPreferences', {
  darkMode: false,
  notifications: true
});

const resetName = () => {
  userName.value = 'Guest';
};
</script>
How it works: This snippet demonstrates how to create a reusable `useLocalStorage` composable in Vue 3's Composition API. This composable encapsulates the logic for persisting and retrieving reactive state to and from the browser's local storage. It uses `ref` to make the stored value reactive, `onMounted` to initialize the value from local storage, and `watch` to automatically update local storage whenever the reactive value changes. It also includes an optional `storage` event listener to synchronize state across multiple tabs or windows.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs