@@ -3,28 +3,63 @@ import { onMounted, ref } from 'vue';
33type Appearance = 'light' | 'dark' | 'system' ;
44
55export function updateTheme ( value : Appearance ) {
6+ if ( typeof window === 'undefined' ) {
7+ return ;
8+ }
9+
610 if ( value === 'system' ) {
7- const systemTheme = window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ? 'dark' : 'light' ;
11+ const mediaQueryList = window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
12+ const systemTheme = mediaQueryList . matches ? 'dark' : 'light' ;
13+
814 document . documentElement . classList . toggle ( 'dark' , systemTheme === 'dark' ) ;
915 } else {
1016 document . documentElement . classList . toggle ( 'dark' , value === 'dark' ) ;
1117 }
1218}
1319
14- const mediaQuery = window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
20+ const setCookie = ( name : string , value : string , days = 365 ) => {
21+ if ( typeof document === 'undefined' ) {
22+ return ;
23+ }
24+
25+ const maxAge = days * 24 * 60 * 60 ;
26+
27+ document . cookie = `${ name } =${ value } ;path=/;max-age=${ maxAge } ;SameSite=Lax` ;
28+ } ;
29+
30+ const mediaQuery = ( ) => {
31+ if ( typeof window === 'undefined' ) {
32+ return null ;
33+ }
34+
35+ return window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
36+ } ;
37+
38+ const getStoredAppearance = ( ) => {
39+ if ( typeof window === 'undefined' ) {
40+ return null ;
41+ }
42+
43+ return localStorage . getItem ( 'appearance' ) as Appearance | null ;
44+ } ;
1545
1646const handleSystemThemeChange = ( ) => {
17- const currentAppearance = localStorage . getItem ( 'appearance' ) as Appearance | null ;
47+ const currentAppearance = getStoredAppearance ( ) ;
48+
1849 updateTheme ( currentAppearance || 'system' ) ;
1950} ;
2051
2152export function initializeTheme ( ) {
53+ if ( typeof window === 'undefined' ) {
54+ return ;
55+ }
56+
2257 // Initialize theme from saved preference or default to system...
23- const savedAppearance = localStorage . getItem ( 'appearance' ) as Appearance | null ;
58+ const savedAppearance = getStoredAppearance ( ) ;
2459 updateTheme ( savedAppearance || 'system' ) ;
2560
2661 // Set up system theme change listener...
27- mediaQuery . addEventListener ( 'change' , handleSystemThemeChange ) ;
62+ mediaQuery ( ) ? .addEventListener ( 'change' , handleSystemThemeChange ) ;
2863}
2964
3065export function useAppearance ( ) {
@@ -42,7 +77,13 @@ export function useAppearance() {
4277
4378 function updateAppearance ( value : Appearance ) {
4479 appearance . value = value ;
80+
81+ // Store in localStorage for client-side persistence...
4582 localStorage . setItem ( 'appearance' , value ) ;
83+
84+ // Store in cookie for SSR...
85+ setCookie ( 'appearance' , value ) ;
86+
4687 updateTheme ( value ) ;
4788 }
4889
0 commit comments