如何在 TanStack Start v1 中实现基于语言环境的路由
使用语言环境段配置路由
问题
在构建多语言应用时,一个最根本的决策会影响后续所有实现:应用如何确定显示哪种语言?如果没有明确的机制,URL /about 就会变得模糊——它可能代表任何语言的内容。用户无法分享特定语言版本的链接,搜索引擎也难以判断每个版本对应的受众。这种不明确会影响用户体验和 SEO,因为无法区分同一内容的不同语言版本。
解决方案
直接在 URL 路径中加入语言标识符,例如 /en/about 或 /fr/about。这样每个路径都唯一对应某种语言,消除了用户和搜索引擎的歧义。通过在路由结构中使用 locale 参数,每个 URL 都能自我描述并便于分享,用户可以收藏或分享自己偏好的语言内容链接,同时也方便搜索引擎正确索引每个语言版本。
步骤
1. 创建语言环境布局路由
使用 {-$locale} 语法定义可选的 locale 参数,以创建灵活的路由模式,使 locale 参数可选。TanStack Start 采用基于文件的路由,路由定义在 src/routes 目录中。
import { createFileRoute, Outlet } from "@tanstack/react-router";
export const Route = createFileRoute("/{-$locale}")({
component: LocaleLayout,
});
function LocaleLayout() {
return <Outlet />;
}
该路由既匹配 /about(locale 未定义),也匹配 /en/about(locale 为 "en"),从而支持带或不带语言前缀的 URL。
2. 在 locale 布局下创建子路由
TanStack Router 使用嵌套路由,根据 URL 匹配并渲染正确的组件树。请将路由文件作为 locale 参数的子级创建,以便从 URL 继承 locale。
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/{-$locale}/about")({
component: AboutPage,
});
function AboutPage() {
const { locale } = Route.useParams();
const currentLocale = locale || "en";
return (
<div>
<h1>About Us</h1>
<p>Current locale: {currentLocale}</p>
</div>
);
}
路由文件结构 {-$locale}/about.tsx 会生成像 /about 和 /en/about 这样的路径,这些路径都会渲染同一个组件,并且可以访问 locale 参数。
3. 在组件中访问 locale 参数
使用 useParams hook 从 URL 读取 locale,并确定显示哪种语言。
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/{-$locale}/products")({
component: ProductsPage,
});
function ProductsPage() {
const { locale } = Route.useParams();
const displayLocale = locale || "en";
return (
<div>
<h1>{displayLocale === "fr" ? "Produits" : "Products"}</h1>
</div>
);
}
当 locale 参数未定义时,组件会默认使用基础语言,从而支持应用同时处理本地化和非本地化的 URL。
4. 创建保留 locale 的链接
使用 Link 组件并传递 locale 参数,在页面间跳转时保持当前语言环境。
import { Link, createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/{-$locale}/")({
component: HomePage,
});
function HomePage() {
const { locale } = Route.useParams();
return (
<nav>
<Link to="/{-$locale}/about" params={{ locale }}>
About
</Link>
<Link to="/{-$locale}/products" params={{ locale }}>
Products
</Link>
</nav>
);
}
通过在 params 属性中传递当前 locale,链接会自动生成与用户当前语言环境相匹配的 URL,例如在查看法语版本时会生成 /fr/about。