問題#
毎回リフレッシュするたびに、ページがフラッシュします。例えば、黒色に設定されたものが初期状態で白色になり、再び黒色に戻る場合です。
原因#
useDark はデフォルトでローカルストレージに保存されますが、ssr 状態ではローカルストレージにアクセスできません。
処理#
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{
innerHTML: `
(function() {
const isDark = localStorage.getItem('darkMode') === 'true' ||
(!localStorage.getItem('darkMode') && window.matchMedia('(prefers-color-scheme: dark)').matches);
document.documentElement.classList.toggle('dark', isDark);
})();
`,
type: 'text/javascript',
},
],
},
},
})
続く問題#
Hydration class mismatch
原因#
フラッシュ問題は解決しましたが、useDark が ssr 時に初期化される値は依然として誤った値です(ローカルストレージにアクセスできません)。
解決#
セッションを使用して保存します。
const isDark = useDark({
storageKey: 'vueuse-color-scheme',
storage: {
getItem(key: string) {
if (import.meta.server) {
// サーバー側はヘッダーからクッキーを取得します
const cookieStr = useRequestHeaders(['cookie'])?.cookie || ''
return cookieStr.split('; ').find(row => row.startsWith(key))?.split('=')[1] || null
}
return document.cookie.split('; ').find(row => row.startsWith(key))?.split('=')[1] || null
},
setItem(key: string, value: string) {
document.cookie = `${key}=${value};path=/;max-age=${60 * 60 * 24 * 30}`
},
} as Storage,
})
// nuxt.config.ts
script: [
{
innerHTML: `
(function() {
var getCookie = function(name) {
return document.cookie.split('; ').find(row => row.startsWith(name))?.split('=')[1] || null;
};
var darkMode = getCookie('vueuse-color-scheme');
if (darkMode === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
})();
`,
type: 'text/javascript',
},
],