Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions app/composables/npm/useOrgPackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,7 @@ import { mapWithConcurrency } from '#shared/utils/async'
* 3. Falls back to lightweight server-side package-meta lookups
*/
export function useOrgPackages(orgName: MaybeRefOrGetter<string>) {
const route = useRoute()
const { searchProvider } = useSearchProvider()
const searchProviderValue = computed(() => {
const p = normalizeSearchParam(route.query.p)
if (p === 'npm' || searchProvider.value === 'npm') return 'npm'
return 'algolia'
})
const searchProviderValue = useEffectiveSearchProvider()
const { getPackagesByName } = useAlgoliaSearch()

const asyncData = useLazyAsyncData(
Expand Down
8 changes: 1 addition & 7 deletions app/composables/npm/useUserPackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,7 @@ const MAX_RESULTS = 250
* ```
*/
export function useUserPackages(username: MaybeRefOrGetter<string>) {
const route = useRoute()
const { searchProvider } = useSearchProvider()
const searchProviderValue = computed(() => {
const p = normalizeSearchParam(route.query.p)
if (p === 'npm' || searchProvider.value === 'npm') return 'npm'
return 'algolia'
})
const searchProviderValue = useEffectiveSearchProvider()
// this is only used in npm path, but we need to extract it when the composable runs
const { $npmRegistry } = useNuxtApp()
const { searchByMaintainer } = useAlgoliaSearch()
Expand Down
13 changes: 4 additions & 9 deletions app/composables/useGlobalSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ const SEARCH_DEBOUNCE_MS = 100

export function useGlobalSearch(place: 'header' | 'content' = 'content') {
const { settings } = useSettings()
const { searchProvider } = useSearchProvider()
const searchProviderValue = computed(() => {
const p = normalizeSearchParam(route.query.p)
if (p === 'npm' || searchProvider.value === 'npm') return 'npm'
return 'algolia'
})
const searchProviderValue = useEffectiveSearchProvider()
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const router = useRouter()
const route = useRoute()
Expand Down Expand Up @@ -85,7 +80,7 @@ export function useGlobalSearch(place: 'header' | 'content' = 'content') {
committedSearchQuery.value = searchQuery.value
// When instant search is off the debounce queue is empty, so call directly
if (!settings.value.instantSearch) {
updateUrlQueryImpl(searchQuery.value, searchProvider.value)
updateUrlQueryImpl(searchQuery.value, searchProviderValue.value)
} else {
updateUrlQuery.flush()
}
Expand All @@ -102,9 +97,9 @@ export function useGlobalSearch(place: 'header' | 'content' = 'content') {

// Leading debounce implementation as it doesn't work properly out of the box (https://github.com/unjs/perfect-debounce/issues/43)
if (!updateUrlQuery.isPending()) {
updateUrlQueryImpl(value, searchProvider.value)
updateUrlQueryImpl(value, searchProviderValue.value)
}
updateUrlQuery(value, searchProvider.value)
updateUrlQuery(value, searchProviderValue.value)
},
})

Expand Down
26 changes: 26 additions & 0 deletions app/composables/useSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useLocalStorage } from '@vueuse/core'
import { ACCENT_COLORS, type AccentColorId } from '#shared/utils/constants'
import type { LocaleObject } from '@nuxtjs/i18n'
import { BACKGROUND_THEMES } from '#shared/utils/constants'
import { normalizeSearchParam } from '#shared/utils/url'

type BackgroundThemeId = keyof typeof BACKGROUND_THEMES

Expand Down Expand Up @@ -218,6 +219,31 @@ export function useSearchProvider() {
}
}

/**
* SSR/hydration-safe search provider for use in async-data cache keys.
* Defers reading the localStorage-backed preference until after `app:mounted`
* so the server-rendered key matches initial hydration.
*/
export function useEffectiveSearchProvider() {
const route = useRoute()
const { searchProvider } = useSearchProvider()

const storedProviderReady = ref(import.meta.server ? false : !useNuxtApp().isHydrating)
if (import.meta.client && !storedProviderReady.value) {
useNuxtApp().hook('app:mounted', () => {
storedProviderReady.value = true
})
}

return computed<SearchProvider>(() => {
const p = normalizeSearchParam(route.query.p)
if (p === 'npm') return 'npm'
if (p === 'algolia') return 'algolia'
if (storedProviderReady.value) return searchProvider.value === 'npm' ? 'npm' : 'algolia'
return DEFAULT_SETTINGS.searchProvider
})
}

export function useBackgroundTheme() {
const { t } = useI18n()

Expand Down
Loading