forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1/**
2 * Initialize user preferences before hydration to prevent flash/layout shift.
3 * This sets CSS custom properties and data attributes that CSS can use
4 * to show the correct content before Vue hydration occurs.
5 *
6 * Call this in app.vue or any page that needs early access to user preferences.
7 */
8export function initPreferencesOnPrehydrate() {
9 // Callback is stringified by Nuxt - external variables won't be available.
10 // All constants must be hardcoded inside the callback.
11 onPrehydrate(() => {
12 // Valid accent color IDs (must match --swatch-* variables defined in main.css)
13 const accentColorIds = new Set(['coral', 'amber', 'emerald', 'sky', 'violet', 'magenta'])
14
15 // Valid package manager IDs
16 const validPMs = new Set(['npm', 'pnpm', 'yarn', 'bun', 'deno', 'vlt'])
17
18 // Read settings from localStorage
19 const settings = JSON.parse(
20 localStorage.getItem('npmx-settings') || '{}',
21 ) as Partial<AppSettings>
22
23 const accentColorId = settings.accentColorId
24 if (accentColorId && accentColorIds.has(accentColorId)) {
25 document.documentElement.style.setProperty('--accent-color', `var(--swatch-${accentColorId})`)
26 }
27
28 // Apply background accent
29 const preferredBackgroundTheme = settings.preferredBackgroundTheme
30 if (preferredBackgroundTheme) {
31 document.documentElement.dataset.bgTheme = preferredBackgroundTheme
32 }
33
34 // Read and apply package manager preference
35 const storedPM = localStorage.getItem('npmx-pm')
36 // Parse the stored value (it's stored as a JSON string by useLocalStorage)
37 let pm = 'npm'
38 if (storedPM) {
39 try {
40 const parsed = JSON.parse(storedPM)
41 if (validPMs.has(parsed)) {
42 pm = parsed
43 }
44 } catch {
45 // If parsing fails, check if it's a plain string (legacy format)
46 if (validPMs.has(storedPM)) {
47 pm = storedPM
48 }
49 }
50 }
51
52 // Set data attribute for CSS-based visibility
53 document.documentElement.dataset.pm = pm
54
55 document.documentElement.dataset.collapsed = settings.sidebar?.collapsed?.join(' ') ?? ''
56 })
57}