在Angular 18 SSR中使用apexcharts/ng-apexcharts遇window未定义错误
解决Angular 18 SSR环境中使用ApexCharts出现的
window is not defined错误 问题原因
ApexCharts库依赖浏览器环境的window对象,而服务器端渲染(SSR)过程中不存在该对象,导致初始化时抛出错误。
解决方案
1. 组件内动态导入+平台判断
在使用图表的组件中,仅在浏览器环境下加载ApexCharts相关依赖,避免服务器端执行相关代码:
首先导入平台判断工具:
import { Component, OnInit, PLATFORM_ID, Inject } from '@angular/core'; import { isPlatformBrowser } from '@angular/common';
然后动态导入图表组件并控制渲染逻辑:
@Component({ selector: 'app-chart', template: ` <div *ngIf="isBrowser"> <apx-chart [series]="series" [chart]="chartOptions"></apx-chart> </div> ` }) export class ChartComponent implements OnInit { isBrowser = false; series!: any[]; chartOptions!: any; constructor(@Inject(PLATFORM_ID) private platformId: Object) {} ngOnInit(): void { this.isBrowser = isPlatformBrowser(this.platformId); if (this.isBrowser) { // 仅在浏览器环境下初始化图表配置 this.series = [{ name: '销量', data: [30, 40, 35, 50, 49, 60, 70, 91, 125] }]; this.chartOptions = { type: 'bar', height: 350, title: { text: '月度销量统计' } }; // 动态导入NgApexcharts模块(若未全局导入) import('ng-apexcharts').then(() => { // 必要时可在此处理组件注册逻辑 }); } } }
2. 全局模块配置:仅在浏览器环境导入NgApexchartsModule
在app.module.ts或核心模块中,通过平台判断决定是否导入图表模块:
import { NgModule, PLATFORM_ID, Inject } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { NgApexchartsModule } from 'ng-apexcharts'; @NgModule({ imports: [ // 其他全局模块 ...(isPlatformBrowser(PLATFORM_ID) ? [NgApexchartsModule] : []) ] }) export class AppModule { constructor(@Inject(PLATFORM_ID) private platformId: Object) {} }
3. Vite SSR配置优化(适配Angular 18的Vite构建)
在vite.config.ts中,将apexcharts标记为SSR外部依赖,避免服务器端打包该库:
import { defineConfig } from 'vite'; import angular from '@angular-devkit/build-angular'; export default defineConfig({ plugins: [angular()], ssr: { external: ['apexcharts'] } });
注意事项
- 所有图表相关的初始化逻辑必须包裹在
isPlatformBrowser判断内,防止服务器端执行浏览器专属代码。 - 若采用全局模块导入方式,需确保服务器端不会触发ApexCharts的初始化流程。
内容的提问来源于stack exchange,提问作者adam lakhmiri
相关产品推荐
相关产品推荐

