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

Angular 6 SSR集成ng-bootstrap报错:ReferenceError: Document is not defined

解决Angular 6 SSR集成ng-bootstrap时的Document is not defined错误

这个报错的本质很明确:服务端渲染(SSR)是在Node.js环境中运行的,这里没有浏览器的Document对象,而你用的ng-bootstrap 2.0.0版本中,NgbFocusTrapFactory这个类在初始化时直接依赖了浏览器的DOM API,导致服务端执行代码时找不到Document,抛出了ReferenceError。

下面给你几个可行的解决方案,按推荐优先级排序:

1. 为服务端提供NgbFocusTrapFactory的替代实现

既然服务端不需要焦点陷阱(焦点管理是浏览器端的交互需求),我们可以创建一个服务端专用的工厂类,覆盖原有的实现,避免在服务端访问Document:

首先,在你的服务端模块(比如app.server.module.ts)所在目录新建一个server-focus-trap.factory.ts文件,内容如下:

import { Injectable, PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformServer } from '@angular/common';
import { NgbFocusTrapFactory } from '@ng-bootstrap/ng-bootstrap';

@Injectable()
export class ServerFocusTrapFactory extends NgbFocusTrapFactory {
  constructor(@Inject(PLATFORM_ID) private platformId: Object) {
    super();
  }

  create(element: HTMLElement) {
    // 如果是服务端环境,返回空的焦点陷阱实现
    if (isPlatformServer(this.platformId)) {
      return {
        trap: () => {},
        release: () => {},
        destroy: () => {}
      };
    }
    // 浏览器环境使用原有的实现
    return super.create(element);
  }
}

然后在app.server.module.ts的providers数组中替换原有的NgbFocusTrapFactory:

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { ServerFocusTrapFactory } from './server-focus-trap.factory';
import { NgbFocusTrapFactory } from '@ng-bootstrap/ng-bootstrap';

@NgModule({
  imports: [AppModule, ServerModule],
  bootstrap: [AppComponent],
  providers: [
    { provide: NgbFocusTrapFactory, useClass: ServerFocusTrapFactory }
  ]
})
export class AppServerModule {}

2. 检查并避免在服务端直接访问DOM API

除了ng-bootstrap的问题,你还要排查自己的代码中有没有在服务端执行的逻辑(比如组件构造函数、ngOnInit等生命周期钩子)中直接访问document或window。如果有,一定要用Angular提供的PLATFORM_ID和isPlatformBrowser/isPlatformServer工具函数做环境判断:

import { Component, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Component({...})
export class YourComponent {
  constructor(@Inject(PLATFORM_ID) private platformId: Object) {}

  ngOnInit() {
    if (isPlatformBrowser(this.platformId)) {
      // 只有浏览器环境才执行DOM相关操作
      document.getElementById('some-element').style.display = 'block';
    }
  }
}

3. 考虑升级ng-bootstrap版本(可选)

ng-bootstrap后续版本(比如3.x及以上)对SSR的兼容性更好,如果你能升级Angular和ng-bootstrap的版本(注意版本匹配:Angular 6对应ng-bootstrap 2.x,Angular 7对应3.x),可能会直接解决这个问题。不过升级前要做好依赖兼容性测试,避免引入新的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:15:23