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
(`/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(`/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' } })