i18n & SEO
How locale routing, canonical URLs, hreflang, and JSON-LD fit together.
Template uses gt.config.json for locale routing and shared SEO helpers for canonical URLs and language alternatives.
Locale-addressed routes
The configured-locale list lives in gt.config.json. gt-next's public helpers provide that list to routing, static generation, metadata, and the fumadocs loader. The default locale is served unprefixed (/docs), other locales under a prefix (/zh/docs).
Locale-neutral Dashboard
The Dashboard keeps one route family at /dash for every configured locale. Its request locale comes from the user's GT preference, then the browser's preferred languages, then the configured default. Changing locale refreshes the translated interface without changing the pathname. Locale-prefixed Dashboard paths such as /zh/dash are invalid rather than alternate URLs.
Dashboard routes are the signed-in product area. They inherit noindex, nofollow metadata and remain outside the sitemap.
Adaptive hreflang
A content locale has a source file in the page's folder: index.mdx for the default locale or index.<locale>.mdx for a translation. Metadata advertises only locales with source content. Requests without a translation use the default-locale canonical URL. Adding or removing a translation updates the page's hreflang alternatives.
Metadata helpers
@zybric/app/lib/seo/build-canonical-url builds canonical URLs, and @zybric/app/lib/seo/build-language-alternatives builds the hreflang languages map. Routes compose these helpers in generateMetadata; the sitemap reuses them. App-specific Open Graph and Twitter defaults live in src/lib/metadata.ts.
Structured data
Blog posts emit BlogPosting + BreadcrumbList (and FAQPage when a post declares faqs); author pages emit Person; the blog index emits ItemList. View source on any content page to see the JSON-LD.