Files
blog/frontend/app/middleware/lang-switch.global.ts
T

43 lines
1.7 KiB
TypeScript
Raw Normal View History

import type { Article, Category } from '#shared/types/blog'
/**
* Resolves the language-switch target *before* the layout (and its header,
* rendered ahead of the page in document order) mounts — setting this from
* inside the page component itself is too late: a parent renders its
* children in document order, so the header's LanguageSwitch would already
* be resolved before the page's own setup ever runs, translated content or
* not. Running as global route middleware guarantees this resolves first.
*/
export default defineNuxtRouteMiddleware(async (to) => {
const langSwitch = useLangSwitchState()
const locale = to.path === '/en' || to.path.startsWith('/en/') ? 'en' : 'it'
const bare = locale === 'en' ? to.path.slice(3) || '/' : to.path
const articleMatch = bare.match(/^\/blog\/([^/]+)$/)
const categoryMatch = bare.match(/^\/category\/([^/]+)$/)
if (articleMatch) {
const slug = articleMatch[1]
const { data } = await useFetch<Article>(`/content/articles/${slug}`, {
key: `article-${slug}-${locale}`,
query: { lang: locale },
})
langSwitch.value = { available: Boolean(data.value?.hasTranslation), fallback: '/en/blog' }
return
}
if (categoryMatch) {
// A category's own translation only gates that specific label — the
// switch always lands somewhere useful (a filtered, possibly empty,
// article list), so it's always shown.
void useFetch<Category>(`/content/categories/${categoryMatch[1]}`, {
key: `category-${categoryMatch[1]}-${locale}`,
query: { lang: locale },
})
langSwitch.value = { available: true, fallback: '/en/blog' }
return
}
langSwitch.value = { available: true, fallback: '/en' }
})