angularfrontendserver-side-renderingapexchartsangular17

Angular 17 SSR Issue with ApexCharts - ReferenceError: window is not defined


I am encountering an issue with my Angular 17 SSR (Server-Side Rendering) application. I am using ApexCharts/ng-apexcharts, which currently only works on the browser side. The specific error message I'm facing is:

enter image description here

I understand that this error is expected in an SSR environment, and disabling SSR resolves the issue. However, I am looking for a more robust solution. After some research, I came across the afterNextRender() function, which seems promising.

I am seeking guidance on how to implement afterNextRender() to handle this situation in an Angular 17 SSR application. I believe this could be a valuable workaround, but I'm struggling with the implementation.

Any help or suggestions would be greatly appreciated. Thank you in advance for your assistance! ps : the chart is displayed but ReferenceError: window is not defined in the terminal is annoying it occurs everytime i import ApexCharts

Here's my current code snippet:

my dashboard.component.ts :

import { AfterRenderPhase, Component, ElementRef, OnInit, ViewChild, afterNextRender } from '@angular/core';
import ApexCharts from 'apexcharts';
import {
  ApexAxisChartSeries,
  ApexChart,
  ApexDataLabels,
  ApexLegend,
  ApexStroke,
  ApexTitleSubtitle,
  ApexXAxis,
  ApexYAxis,
} from 'ng-apexcharts';
export type ChartOptions = {
  series: ApexAxisChartSeries;
  chart: ApexChart;
  xaxis: ApexXAxis;
  stroke: ApexStroke;
  dataLabels: ApexDataLabels;
  yaxis: ApexYAxis;
  title: ApexTitleSubtitle;
  labels: string[];
  legend: ApexLegend;
  subtitle: ApexTitleSubtitle;
};
export const series = {
  // dummy data from apex docs
};
@Component({
  selector: 'app-dashboard',
  standalone: true,
  imports: [],
  templateUrl: './dashboard.component.html',
  styleUrl: './dashboard.component.scss'
})
export class DashboardComponent implements OnInit {
  @ViewChild('chart') chart!: ElementRef;
  public chartOptions!: Partial<ChartOptions>;

  constructor() {
    // im struggling here
    afterNextRender(() => {
      const element = this.chart.nativeElement;
      var chart = new ApexCharts(element, this.chartOptions);
      chart.render()
    }, {phase: AfterRenderPhase.Read});
  }
 

  ngOnInit(): void {
    this.chartOptions = {
      series: [
        {
          name: 'STOCK ABC',
          data: series.monthDataSeries1.prices,
        },
      ],
      // chart options config from apex docs
    };
  }
}

in my dashboard.component.html

<div #chart  id="chart"> </div>

Solution

  • If looks like it doesn't support SSR at the moment.

    Your alternative could be to lazy-load the lib with a dynamic import (not a require) :

    const apexChart = await import('apexcharts'); var chart = new ApexCharts(element, this.chartOptions); chart.render()

    and running all this in afterNextRender().