// Root layout — wraps every page in the framework's BlogLayout shell inside a // URL-driven (Strategy B: en at the bare path, de under /de). // `voltro build` pre-renders each page once per locale with the right catalog // baked in. The language switcher goes in BlogLayout's `headerRight` slot as a // plain per locale — a real navigation to that locale's crawlable URL, // which is correct for a zero-JS static content site. // // BlogLayout carries its own inline styles; globals.css only styles the // markdown body + the list. import type { ReactNode } from 'react' import { BlogLayout, useLocation } from '@voltro/web' import { I18nProvider, T, useLocale, useT } from '@voltro/i18n' import { CATALOGS, DEFAULT_LOCALE, SUPPORTED_LOCALES, stripLocalePrefix, useUrlLocale, withLocalePrefix, } from '../lib/locale' import '../globals.css' interface LayoutProps { readonly children: ReactNode } // Rendered INSIDE the provider so / useT resolve against the active // catalog. topNav labels must be plain strings, so they come from useT. function ChangelogShell({ children }: LayoutProps): ReactNode { const locale = useLocale() const pathname = useLocation() const barePath = stripLocalePrefix(pathname) const releasesLabel = useT('nav.releases') const rssLabel = useT('nav.rss') return ( {{capProjectName}} } pathname={pathname} topNav={[ { label: releasesLabel, href: withLocalePrefix('/', locale) }, // One shared feed for every locale — never locale-prefixed. { label: rssLabel, href: '/rss.xml' }, ]} headerRight={ : {SUPPORTED_LOCALES.map((code) => ( {code.toUpperCase()} ))} } footer={ } > {children} ) } export default function Layout({ children }: LayoutProps): ReactNode { const locale = useUrlLocale() return ( {children} ) }