Angular 18 SSR+本地化:带参数路由直接访问报404问题
解决Angular 18 SSR+多语言本地化下带参数路由直接访问404的问题
问题核心原因
启用本地化后,Angular生成了带语言前缀的目录结构,但Vercel的默认路由规则无法正确识别带参数的语言前缀路由,直接访问时会去寻找不存在的静态文件,从而触发404。而应用内导航由Angular客户端路由处理,不受静态文件规则限制,所以正常。
解决方案
1. 配置Vercel重写规则(项目根目录创建vercel.json)
通过重写规则将所有带语言前缀的路由转发到对应语言的SSR服务器入口,让Angular负责路由解析:
{ "rewrites": [ { "source": "/en/(.*)", "destination": "/dist/app/server/en/main.js" }, { "source": "/es/(.*)", "destination": "/dist/app/server/es/main.js" }, { "source": "/(.*)", "destination": "/en/$1" } ] }
2. 调整server.ts适配语言前缀路由
在SSR入口文件中,从请求URL提取语言代码,动态设置APP_BASE_HREF和本地化配置:
import { APP_BASE_HREF } from '@angular/common'; import { bootstrapApplication } from '@angular/platform-browser'; import { AppComponent } from './src/app/app.component'; import { provideRouter } from '@angular/router'; import { routes } from './src/app/app.routes'; import { provideClientHydration } from '@angular/platform-browser'; import { provideI18n } from '@angular/localize'; // 从URL中提取语言标识,仅处理en/es function extractLangFromUrl(url: string): string { const pathSegments = url.split('/').filter(seg => seg); if (pathSegments.length > 0 && ['en', 'es'].includes(pathSegments[0])) { return pathSegments[0]; } return 'en'; // 默认 fallback 到英文 } export function app(request: Request) { const lang = extractLangFromUrl(request.url); const baseHref = `/${lang}/`; return bootstrapApplication(AppComponent, { providers: [ provideRouter(routes), provideClientHydration(), provideI18n({ locale: lang }), { provide: APP_BASE_HREF, useValue: baseHref } ] }).then(appRef => appRef.renderToString()); }
3. 验证构建与部署
确保构建命令使用SSR模式:
ng build --ssr
将vercel.json放在项目根目录后,重新部署到Vercel即可。
关键说明
- 无参数路由直接访问正常,是因为Vercel默认会匹配到对应语言目录下的
index.html,而带参数路由没有对应的静态文件,必须通过SSR服务器解析。 - 重写规则确保所有带语言前缀的请求都被转发到对应的SSR入口,由Angular处理路由参数解析和页面渲染。
内容的提问来源于stack exchange,提问作者Jonathan Anastasi
相关产品推荐
相关产品推荐

