How to have localized links in ContentSearch?
Package
v4.x
Description
I’m using @nuxt/content, @nuxt/ui, and @nuxtjs/i18n together, and I’m trying to have localized URLs in the search results rendered by the <UContentSearch> component.
Currently, the component works fine and fetches all the correct results, but the item.path values are always non-localized (e.g. /blog/my-post instead of /sk/blog/my-post).
Even though my site is fully localized and I’m correctly fetching content from language-specific collections like blogs_en and blogs_sk.
I couldn’t find a built-in way to localize the links inside the search results. Is there a recommended approach to make <UContentSearch> output localized URLs?
What I tried
-
Transforming the urls when fetching the navigation and searchSections, which works but, all the results are highlighted by default, because my guess is that NuxtLinks is-active is not set to exact url path.
-
Setting locale prefix to nuxt/content collection, for example for sk locale it would be
/sk/blog. This worked as well but the result was as in the point 1.
This is how I fetch the data ( Version with the transformations )
const { locale, t } = useI18n();
const localePath = useLocalePath();
const route = useRoute();
const normalizedPath = computed(() =>
withLeadingSlash(joinURL("blog", ...(Array.isArray(route.params.slug) ? route.params.slug : [route.params.slug])))
);
const { data: page } = await useAsyncData(
normalizedPath.value,
() => queryCollection(`blogs_${locale.value}`).path(normalizedPath.value).first(),
{ watch: [locale, route] }
);
const { data: navigation } = await useAsyncData(
`navigation-${locale.value}-${normalizedPath.value}`,
async () => {
const nav = await queryCollectionNavigation(`blogs_${locale.value}`).where(
"path",
"LIKE",
`%${normalizedPath.value}%`
);
const transformNav = (items) =>
items.map((item) => ({
...item,
path: localePath(item.path),
children: item.children ? transformNav(item.children) : undefined,
}));
return transformNav(nav);
},
{ watch: [locale, route] }
);
const { data: searchSections } = await useLazyAsyncData(
`search-sections-${locale.value}-${normalizedPath.value}`,
() =>
queryCollectionSearchSections(`blogs_${locale.value}`).where(
"path",
"LIKE",
`%${normalizedPath.value}%`
),
{
watch: [locale, route],
server: false,
}
);
This is how I render the ContentSearch
<ClientOnly>
<UContentSearch
shortcut="meta_shift_k"
:navigation="navigation"
:files="searchSections"
autofocus
:fuse="{ resultLimit: 20 }"
:placeholder="$t('blogDetail.searchInArticle')"
:color-mode="false"
:ui="{}"
>
<template #empty="{ searchTerm }">
<template v-if="searchTerm">
{{ $t("blogDetail.searchEmpty") }}
"{{ searchTerm }}"
</template>
</template>
</UContentSearch>
</ClientOnly>
Thank you in advance for any suggestions.