Angular 18集成Keycloak 24.0.2初始化报错:document is not defined
解决Angular 18集成Keycloak 24.0.2时的"document is not defined"错误
这个错误的核心原因是Angular 18默认启用了客户端 hydration 或 SSR(服务器端渲染),在服务器端执行APP_INITIALIZER时,没有浏览器环境中的document对象,而keycloak-js依赖浏览器DOM才能正常初始化。
解决方案:仅在浏览器环境初始化Keycloak
- 修改初始化函数,添加平台环境判断
在initializeKeycloak中注入PLATFORM_ID,通过isPlatformBrowser判断当前是否为浏览器环境,非浏览器环境直接返回成功Promise:
import Keycloak from 'keycloak-js'; import { KeycloakService } from 'keycloak-angular'; import { isPlatformBrowser, PLATFORM_ID } from '@angular/common'; import { inject } from '@angular/core'; export function initializeKeycloak(keycloak: KeycloakService): () => Promise<boolean> { return (): Promise<boolean> => { const platformId = inject(PLATFORM_ID); // 跳过服务器端初始化,仅在浏览器环境执行Keycloak初始化 if (!isPlatformBrowser(platformId)) { return Promise.resolve(true); } return keycloak.init({ config: { url: 'http://localhost:8080/auth', realm: 'MyRealm', clientId: 'angular-app', }, initOptions: { onLoad: 'login-required', }, }); }; }
- 更新
app.config的依赖配置
在APP_INITIALIZER的deps数组中添加PLATFORM_ID,确保初始化函数能获取到平台标识:
export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideClientHydration(), KeycloakService, { provide: APP_INITIALIZER, useFactory: initializeKeycloak, multi: true, deps: [KeycloakService, PLATFORM_ID] // 新增PLATFORM_ID依赖 } ] };
额外注意事项
- Keycloak 24.x 默认移除了路径中的
/auth,如果你的Keycloak实例是默认配置,建议将url修改为http://localhost:8080,避免路径错误导致的后续问题。 - 若你不需要SSR或客户端 hydration,可以在创建项目时通过
--ssr false禁用,也能避免此类服务器端与浏览器环境的冲突,但不推荐在生产环境关闭该特性。
内容的提问来源于stack exchange,提问作者roconmachine
相关产品推荐
相关产品推荐

