@@ -74,18 +74,31 @@ const STORAGE_KEY = 'npmx-settings'
7474/**
7575 * Read settings from localStorage and merge with defaults.
7676 */
77+ function normaliseSettings ( input : AppSettings ) : AppSettings {
78+ return {
79+ ...input ,
80+ searchProvider : input . searchProvider === 'npm' ? 'npm' : 'algolia' ,
81+ sidebar : {
82+ ...input . sidebar ,
83+ collapsed : Array . isArray ( input . sidebar ?. collapsed )
84+ ? input . sidebar . collapsed . filter ( ( v ) : v is string => typeof v === 'string' )
85+ : [ ] ,
86+ } ,
87+ }
88+ }
89+
7790function readFromLocalStorage ( ) : AppSettings {
7891 try {
7992 const raw = localStorage . getItem ( STORAGE_KEY )
8093 if ( raw ) {
8194 const stored = JSON . parse ( raw )
82- return {
95+ return normaliseSettings ( {
8396 ...DEFAULT_SETTINGS ,
8497 ...stored ,
8598 connector : { ...DEFAULT_SETTINGS . connector , ...stored . connector } ,
8699 sidebar : { ...DEFAULT_SETTINGS . sidebar , ...stored . sidebar } ,
87100 chartFilter : { ...DEFAULT_SETTINGS . chartFilter , ...stored . chartFilter } ,
88- }
101+ } )
89102 }
90103 } catch { }
91104 return { ...DEFAULT_SETTINGS }
@@ -111,11 +124,18 @@ export function useSettings() {
111124 // Read localStorage eagerly but apply after mount to prevent hydration
112125 // mismatch. During hydration, useState provides server-matching defaults.
113126 // After mount, we swap in the user's actual preferences from localStorage.
127+ // Uses nuxtApp.hook('app:mounted') instead of onMounted so it works even
128+ // when useSettings() is first called from a plugin (no component context).
114129 const stored = readFromLocalStorage ( )
130+ const nuxtApp = useNuxtApp ( )
115131
116- onMounted ( ( ) => {
132+ if ( nuxtApp . isHydrating ) {
133+ nuxtApp . hook ( 'app:mounted' , ( ) => {
134+ settings . value = stored
135+ } )
136+ } else {
117137 settings . value = stored
118- } )
138+ }
119139
120140 // Persist future changes back to localStorage
121141 watch (
0 commit comments