如何在SSR友好的懒加载路由中获取文档lang属性或URL语言标识
Angular SSR下懒加载路由时获取语言信息的解决方案
方法1:通过全局单例服务预存语言信息
- 创建全局语言服务,同时兼容服务端和浏览器环境:
import { Injectable, PLATFORM_ID, inject } from '@angular/core'; import { isPlatformServer } from '@angular/common'; import { REQUEST } from '@nguniversal/express-engine/tokens'; @Injectable({ providedIn: 'root' }) export class LanguageService { private lang: string | null = null; constructor() { const platformId = inject(PLATFORM_ID); if (isPlatformServer(platformId)) { // 服务端从请求URL解析语言 const request = inject(REQUEST); const urlSegments = request.url.split('/'); this.lang = urlSegments[1] || 'en'; } else { // 浏览器从document的lang属性获取 this.lang = document.documentElement.lang || 'en'; } } getLang(): string { return this.lang || 'en'; } }
- 在应用初始化时确保服务提前加载(可选,因
providedIn: root会自动初始化):
// appConfig.ts export const appConfig: ApplicationConfig = { providers: [ { provide: APP_INITIALIZER, useFactory: (langService: LanguageService) => () => Promise.resolve(), deps: [LanguageService], multi: true }, // 其他提供者... ] };
- 在懒加载路由中注入服务获取语言:
import { LanguageService } from './language.service'; export const appRoutes: Route[] = [ { path: 'testing', loadChildren: () => { const langService = inject(LanguageService); return import('./my-lazy-loaded-routes').then(m => { const lang = langService.getLang(); return translateRoutes(m.MyLazyLoadedRoutes, lang); }); } } ];
方法2:直接从URL解析语言(无需额外服务)
如果语言码是URL路径的第一部分(如/en/testing),可直接在懒加载逻辑中解析当前URL:
import { PLATFORM_ID, inject } from '@angular/core'; import { isPlatformServer } from '@angular/common'; import { REQUEST } from '@nguniversal/express-engine/tokens'; export const appRoutes: Route[] = [ { path: 'testing', loadChildren: () => { const platformId = inject(PLATFORM_ID); let lang = 'en'; // 设置默认语言 if (isPlatformServer(platformId)) { const request = inject(REQUEST); const urlSegments = request.url.split('/'); lang = urlSegments[1] || lang; } else { const urlSegments = window.location.pathname.split('/'); lang = urlSegments[1] || document.documentElement.lang || lang; } return import('./my-lazy-loaded-routes').then(m => { return translateRoutes(m.MyLazyLoadedRoutes, lang); }); } } ];
关于你尝试的ApplicationRefPromise问题
你用Promise.all无响应是因为路由加载属于Angular引导流程的一部分,而ApplicationRefPromise是引导完成的Promise,两者互相等待导致死锁:路由加载等待引导完成,引导完成又依赖路由加载完成。因此单独调用ApplicationRefPromise.then时,引导完成后会触发回调,但Promise.all会一直处于pending状态,这种方式不可行。
内容的提问来源于stack exchange,提问作者Chrillewoodz
相关产品推荐
相关产品推荐

