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

Angular 17 SSR集成第三方组件报错window is not defined如何解决?

解决Angular 17 SSR下使用@impactech/sidenav出现"window is not defined"的问题

错误原因是@impactech/sidenav组件在初始化时直接访问了浏览器专属的window对象,但SSR过程在Node.js服务端执行,不存在该对象,因此触发报错。以下是几种可行的解决方法:

方法一:通过环境判断控制组件渲染

利用Angular的isPlatformBrowser工具,仅在浏览器环境下渲染侧边栏组件:

  1. 修改app.component.ts:
import { Component, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { SideBarComponent, SidebarItemComponent  } from '@impactech/sidenav';

@Component({
    selector: 'app-root',
    standalone: true,
    imports: [RouterOutlet, SideBarComponent, SidebarItemComponent],
    templateUrl: './app.component.html',
    styleUrl: './app.component.scss'
})
export class AppComponent {
  isBrowser: boolean;

  constructor(@Inject(PLATFORM_ID) private platformId: Object) {
    this.isBrowser = isPlatformBrowser(platformId);
  }
}
  1. 修改app.component.html:
<router-outlet>
    <impactech-sidebar *ngIf="isBrowser">
        <impactech-sidebar-item type="header" label="Header"></impactech-sidebar-item>
        <impactech-sidebar-item label="item without icon" link="#"></impactech-sidebar-item>
        <impactech-sidebar-item bottom label="item at bottom" link="#" icon="icons8-o-settings"></impactech-sidebar-item>
    </impactech-sidebar>
<router-outlet/>

方法二:动态导入组件(避免服务端解析)

仅在浏览器环境下动态导入组件,彻底避免服务端加载依赖window的代码:

修改app.component.ts:

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

@Component({
    selector: 'app-root',
    standalone: true,
    imports: [RouterOutlet],
    template: `
      <router-outlet>
        <ng-template #sidebarContainer></ng-template>
      </router-outlet>
    `,
    styleUrl: './app.component.scss'
})
export class AppComponent implements OnInit {
  @ViewChild('sidebarContainer', { read: ViewContainerRef }) sidebarContainer!: ViewContainerRef;
  isBrowser: boolean;

  constructor(@Inject(PLATFORM_ID) private platformId: Object) {
    this.isBrowser = isPlatformBrowser(platformId);
  }

  async ngOnInit() {
    if (this.isBrowser) {
      const { SideBarComponent, SidebarItemComponent } = await import('@impactech/sidenav');
      
      // 创建侧边栏组件
      const sidebarRef = this.sidebarContainer.createComponent(SideBarComponent);
      
      // 动态添加子项(示例)
      const headerItem = sidebarRef.instance.contentContainer.createComponent(SidebarItemComponent);
      headerItem.instance.type = 'header';
      headerItem.instance.label = 'Header';

      // 重复上述逻辑添加其他侧边栏项
    }
  }
}

方法三:服务端模拟window对象(临时方案,不推荐)

在server.ts顶部添加window模拟,仅适用于库依赖的window属性较少的场景:

(global as any).window = {
  innerWidth: 1920,
  innerHeight: 1080
  // 根据库的需求补充其他window属性
};

注:此方法可能因属性不全引发其他异常,仅作为临时应急方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 05:24:54