-
-
Notifications
You must be signed in to change notification settings - Fork 424
Expand file tree
/
Copy pathprehydrate.ts
More file actions
88 lines (77 loc) · 2.93 KB
/
prehydrate.ts
File metadata and controls
88 lines (77 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* Initialize user preferences before hydration to prevent flash/layout shift.
* This sets CSS custom properties and data attributes that CSS can use
* to show the correct content before Vue hydration occurs.
*
* Call this in app.vue or any page that needs early access to user preferences.
*/
export function initPreferencesOnPrehydrate() {
// Callback is stringified by Nuxt - external variables won't be available.
// All constants must be hardcoded inside the callback.
onPrehydrate(() => {
// Valid accent color IDs (must match --swatch-* variables defined in main.css)
const accentColorIds = new Set([
'sky',
'coral',
'amber',
'emerald',
'violet',
'magenta',
'neutral',
] satisfies typeof ACCENT_COLOR_IDS)
// Valid package manager IDs
const validPMs = new Set(['npm', 'pnpm', 'yarn', 'bun', 'deno', 'vlt', 'vp'])
// Read settings from localStorage
const settings = JSON.parse(
localStorage.getItem('npmx-settings') || '{}',
) as Partial<AppSettings>
const accentColorId = settings.accentColorId
if (accentColorId && accentColorIds.has(accentColorId)) {
document.documentElement.style.setProperty('--accent-color', `var(--swatch-${accentColorId})`)
}
// Apply background accent
const preferredBackgroundTheme = settings.preferredBackgroundTheme
if (preferredBackgroundTheme) {
document.documentElement.dataset.bgTheme = preferredBackgroundTheme
}
let pm = 'npm'
// Support package manager preference in query string (for example, ?pm=pnpm)
const queryPM = new URLSearchParams(window.location.search).get('pm')
if (queryPM && validPMs.has(queryPM)) {
pm = queryPM
localStorage.setItem('npmx-pm', pm)
} else {
// Read and apply package manager preference
const storedPM = localStorage.getItem('npmx-pm')
// Parse the stored value (it's stored as a JSON string by useLocalStorage)
if (storedPM) {
try {
const parsed = JSON.parse(storedPM)
if (validPMs.has(parsed)) {
pm = parsed
}
} catch {
// If parsing fails, check if it's a plain string (legacy format)
if (validPMs.has(storedPM)) {
pm = storedPM
}
}
}
}
// Set data attribute for CSS-based visibility
document.documentElement.dataset.pm = pm
document.documentElement.dataset.collapsed = settings.sidebar?.collapsed?.join(' ') ?? ''
// Keyboard shortcuts (default: true)
if (settings.keyboardShortcuts === false) {
document.documentElement.dataset.kbdShortcuts = 'false'
}
// Search provider (default: algolia)
if (settings.searchProvider === 'npm') {
document.documentElement.dataset.searchProvider = 'npm'
}
// Code font ligatures (default: true)
if (settings.codeLigatures === false) {
document.documentElement.dataset.codeLigatures = 'false'
}
})
}