Client Only - Local Storage

I created a global store that's backed by window.localstorage. I don't think that I can use clientOnly because the module doesn't export an Element. What do I do?
import { createEffect } from "solid-js";
import { createStore } from "solid-js/store";

interface AppState {
accessToken?: string;
itemId?: string;
}

const pair = window.localStorage.getItem("item");
const [itemId, accessToken] = pair?.split("|") || [];

export const [appState, setAppState] = createStore<AppState>({
itemId,
accessToken
})

createEffect(() => {
if (appState.itemId && appState.accessToken) {
const value = `${appState.itemId}|${appState.accessToken}`;
window.localStorage.setItem("item", value);
} else {
window.localStorage.removeItem("item");
}
})
import { createEffect } from "solid-js";
import { createStore } from "solid-js/store";

interface AppState {
accessToken?: string;
itemId?: string;
}

const pair = window.localStorage.getItem("item");
const [itemId, accessToken] = pair?.split("|") || [];

export const [appState, setAppState] = createStore<AppState>({
itemId,
accessToken
})

createEffect(() => {
if (appState.itemId && appState.accessToken) {
const value = `${appState.itemId}|${appState.accessToken}`;
window.localStorage.setItem("item", value);
} else {
window.localStorage.removeItem("item");
}
})
4 Replies
jrainearwills
jrainearwillsOP3mo ago
i guess that i can move the localstorage part into a component.
Alex Lohr
Alex Lohr3mo ago
Use makePersisted from @solid-primitives/storage, it will automatically persist any signal or store for you and even just return it if there is no storage given (localStorage is the default, none on the server).
NitonFx
NitonFx3mo ago
you can use the isServer if you dont need the state to be available and renderable on the server. BUT i think what you are searching for is better suited as a standalone primitive such as the one provided by @solid-primitives or something homemade and simpler
function createLocalStore<T>(key:string, parse: (string)=>T, format: (T)=>string){
if(isServer) return [/*whatever the fallback should be server side*/];
const pair = window.localStorage.getItem(key);
export const [appState, setAppState] = createStore<T>(parse(pair))

createEffect(() => {
if (appState.itemId && appState.accessToken) {
const value = format(appState);
window.localStorage.setItem(key, value);
} else {
window.localStorage.removeItem(key);
}
})
}
function createLocalStore<T>(key:string, parse: (string)=>T, format: (T)=>string){
if(isServer) return [/*whatever the fallback should be server side*/];
const pair = window.localStorage.getItem(key);
export const [appState, setAppState] = createStore<T>(parse(pair))

createEffect(() => {
if (appState.itemId && appState.accessToken) {
const value = format(appState);
window.localStorage.setItem(key, value);
} else {
window.localStorage.removeItem(key);
}
})
}
which you can then use
createLocalStore("item", str => str.split("|"), obj => `${obj[0]}|${obj[1]}`);
createLocalStore("item", str => str.split("|"), obj => `${obj[0]}|${obj[1]}`);
Hussein
Hussein3mo ago
you can also import the module in onMount with dynamic import()
Want results from more Discord servers?
Add your server