You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Universal SSR下如何在app-routing.module.ts中使用platformId变量

解决方案

问题根因

你直接在模块顶层定义routes常量时处于静态初始化阶段,还未进入Angular依赖注入的运行时周期,无法直接拿到注入的PLATFORM_ID,且服务端运行环境不存在localStorage API,直接调用会报错。

方案1:使用路由守卫(全Angular版本兼容)

这是兼容性最好的方案,所有支持Angular Universal的版本都可以使用:

  1. 首先创建一个重定向守卫:
// src/app/redirect-home.guard.ts
import { Injectable, Inject } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class RedirectHomeGuard implements CanActivate {
  constructor(
    @Inject(PLATFORM_ID) private platformId: Object,
    private router: Router
  ) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): UrlTree | boolean {
    if (isPlatformBrowser(this.platformId)) {
      const countryCode = localStorage.getItem('countryCode') || 'my';
      return this.router.parseUrl(`/${countryCode}`);
    }
    // 服务端环境直接走默认国别路径
    return this.router.parseUrl('/my');
  }
}
  1. 修改app-routing.module.ts的路由配置:
import { RedirectHomeGuard } from './redirect-home.guard';

const routes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    canActivate: [RedirectHomeGuard]
  },
  // 保留你原有其他路由配置
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      scrollPositionRestoration: 'enabled',
      onSameUrlNavigation: 'reload'
    })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {}

方案2:使用Angular 14+ 注入式redirectTo函数

如果你使用的是Angular 14及以上版本,可以直接使用支持依赖注入的redirectTo函数写法,代码更简洁:

// app-routing.module.ts
import { NgModule, inject, PLATFORM_ID } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { isPlatformBrowser } from '@angular/common';

const routes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    redirectTo: () => {
      const platformId = inject(PLATFORM_ID);
      if (isPlatformBrowser(platformId)) {
        return localStorage.getItem('countryCode') || 'my';
      }
      return 'my';
    }
  }
  // 保留你原有其他路由配置
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      scrollPositionRestoration: 'enabled',
      onSameUrlNavigation: 'reload'
    })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {}

注意事项

服务端渲染返回的路径需要和客户端首次渲染的路径保持一致,避免hydration不匹配报错,所以两种方案默认服务端都返回/my路径。如果需要优化体验,你也可以在服务端通过请求头的Accept-Language或者IP解析获取用户国别,替代默认的my参数,避免客户端二次跳转。

内容的提问来源于stack exchange,提问作者Bhavya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 22:24:01