Featured image of post 【Svelte Store】解決編譯錯誤訊息「Error: localStorage is not defined」與 localStorage 同步儲存資料

【Svelte Store】解決編譯錯誤訊息「Error: localStorage is not defined」與 localStorage 同步儲存資料

【Svelte Store】解決編譯錯誤訊息「Error: localStorage is not defined」與 localStorage 同步儲存資料

在 Sveltekit 使用 localStorage

因為 Sveltekit 是在 Server 端編譯再到 client 端執行,所以如果要直接執行存取 localStorage 會出現 Error: localStorage is not defined 的錯誤訊息

window.localStorage.setItem('theme', 'dark');

所以必須加入環境變數判斷,確定是瀏覽器環境再執行,這樣就可以順利完成編譯

import { browser } from '$app/environment';

if (browser) {
  window.localStorage.setItem('theme', 'dark');
}

Svelte Store 與 localStorage 資料同步

原始碼函式

Ref: Sveltekit and localstorage sync : r/sveltejs

在 Svelte Store 資料異動時,直接將結果儲存到 localStorage

// $lib/Core/StorageSupport.js
import { browser } from '$app/environment';
import { writable, get } from 'svelte/store'

export function LocalStorageStore(key: string, initValue: any) {
  const store = writable(initValue);
  if (!browser) {
    console.log("no browser")
    return store
  };

  const storedValueStr = localStorage.getItem(key);
  if (storedValueStr != null) {
    store.set(JSON.parse(storedValueStr))
  }

  store.subscribe((val) => {
    if ([null, undefined].includes(val)) {
      localStorage.removeItem(key)
    } else {
      localStorage.setItem(key, JSON.stringify(val))
    }
  })

  window.addEventListener('storage', () => {
    const storedValueStr = localStorage.getItem(key);
    if (storedValueStr == null) return;

    const localValue = JSON.parse(storedValueStr)
    if (localValue !== get(store)) store.set(localValue);
  });

  return store;
}

使用自定義 Store 函式只要要儲存的 key 及 data

import { LocalStorageStore } from '$lib/Core/StorageSupport';

let sync_data = {
  email: 'my@email',
}

export const LocalSyncStore = LocalStorageStore('sync_data', sync_data);

變更 Store 資料

變更資料後就可以在看到 localStorage 也同步的將這個資料儲存起來了!

import { LocalSyncStore } from '$lib/LocalSyncStore';
$LocalSyncStore.email = 'other@email';

使用 svelte-persisted-store 將資料儲存到 localStorage

import { browser } from '$app/environment';
import { persisted } from 'svelte-persisted-store'

// First param `preferences` is the local storage key.
// Second param is the initial value.


if (browser) {
  const preferences = persisted('preferences', {})
  preferences.set({
    theme: 'dark',
    pane: '50%',
  })
}
import { get } from 'svelte/store'
import { preferences } from './stores'

preferences.subscribe(...) // subscribe to changes
preferences.update(...) // update value
preferences.set(...) // set value
preferences.reset() // reset to initial value
get(preferences) // read value
$preferences // read value with automatic subscription

Reference

Donate KJ 贊助作者喝咖啡

如果這篇文章對你有幫助的話,可以透過下面支付方式贊助作者喝咖啡,如果有什麼建議或想說的話可以贊助並留言給我
If this article has been helpful to you, you can support the author by treating them to a coffee through the payment options below. If you have any suggestions or comments, feel free to sponsor and leave a message for me!
方式 Method 贊助 Donate
PayPal https://paypal.me/kejyun
綠界 ECPay https://p.ecpay.com.tw/AC218F1
歐付寶 OPay https://payment.opay.tw/Broadcaster/Donate/BD2BD896029F2155041C8C8FAED3A6F8
All rights reserved,未經允許不得隨意轉載
Built with Hugo
Theme Stack designed by Jimmy