JAVASCRIPT
Vue 3 useLocalStorageRef Composable
Create a custom Vue 3 `ref` that automatically synchronizes its value with browser's `localStorage`, providing reactive and persistent state management.
import { customRef } from 'vue';
function useLocalStorageRef(key, defaultValue) {
let value = defaultValue;
let storedValue;
// Check if localStorage is available (client-side only)
if (typeof window !== 'undefined' && window.localStorage) {
try {
storedValue = localStorage.getItem(key);
if (storedValue !== null) {
value = JSON.parse(storedValue);
} else {
localStorage.setItem(key, JSON.stringify(defaultValue));
}
} catch (e) {
console.error('Error reading from localStorage:', e);
// Fallback to default value if localStorage access fails
value = defaultValue;
}
}
return customRef((track, trigger) => {
return {
get() {
track();
return value;
},
set(newValue) {
// Only update if the new value is different
if (newValue !== value) {
value = newValue;
// Persist to localStorage
if (typeof window !== 'undefined' && window.localStorage) {
try {
localStorage.setItem(key, JSON.stringify(newValue));
} catch (e) {
console.error('Error writing to localStorage:', e);
}
}
trigger(); // Notify Vue to re-render
}
},
};
});
}
// Example Usage in a component:
// <script setup>
// import useLocalStorageRef from './composables/useLocalStorageRef';
// const userName = useLocalStorageRef('user_name', 'Guest');
// </script>
// <template>
// <input v-model="userName" placeholder="Enter your name" />
// <p>Hello, {{ userName }}!</p>
// </template>
export default useLocalStorageRef;
How it works: This `useLocalStorageRef` composable leverages Vue 3's `customRef` to create a reactive reference that automatically persists its value to `localStorage`. Upon initialization, it attempts to load the value from `localStorage`; if not found, it uses the provided `defaultValue`. Any subsequent changes to the ref's value are automatically saved, ensuring state persistence across page reloads. The `track` and `trigger` functions from `customRef` manage Vue's reactivity system, making the ref fully reactive like a standard `ref`.