react-apexcharts icon indicating copy to clipboard operation
react-apexcharts copied to clipboard

Support Nextjs@13 / React server components (window is not defined)

Open lokimckay opened this issue 2 years ago • 7 comments

Apex Charts tries to access the window object without checking it is available first, so it does not work in server contexts. The workaround is to ensure the library is only used in a browser context

In NextJS, the usual method of ensuring a module only renders on the client is to use next/dyanamic with SSR disabled, but this approach doesn't work in NextJS 13:

// nextjs13 - doesn't work - gives "window is not defined"
"use client";
import dynamic from "next/dynamic";
const Chart = dynamic(() => import("react-apexcharts"), { ssr: false });

export default function ApexChart(props: any) {
  return <Chart {...props} />;
}

My current workaround is to import "react-apexcharts" inside a useEffect to force NextJS to only import on the client side:

// nextjs13 - works
"use client";
import { useEffect, useState } from "react";

export default function ApexChart(props: any) {
  const [Chart, setChart] = useState<any>();
  const hasType = typeof props?.type !== "undefined";

  useEffect(() => {
    import("react-apexcharts").then((mod) => {
      setChart(() => mod.default);
    });
  }, []);

  return hasType && Chart && <Chart {...props} />;
}

But IMO I feel this is unnecessary if the Apex Charts library would just check that the window object is available first before trying to access it

Related issues:

  • https://github.com/apexcharts/react-apexcharts/issues/425
  • https://github.com/apexcharts/react-apexcharts/issues/358
  • https://github.com/apexcharts/react-apexcharts/issues/240

lokimckay avatar Jan 07 '23 03:01 lokimckay

Although not very elegant, it solved my problem. I think we should add an undefined check for the window in the project.

kamtorocks avatar Apr 06 '23 07:04 kamtorocks

We're facing the same issue in our project, SSR is breaking duo to Apex Charts. A proper fix would be great. We used the useEffect workaround, it works but it's nasty!

jaapaurelio avatar Apr 20 '23 13:04 jaapaurelio

Yeah, i am facing this issue too. We need proper fix to solve this problem

dipras avatar Jun 03 '23 07:06 dipras

Got hit with a similar issue today,

Codedwells avatar Jul 31 '23 22:07 Codedwells

I'm also facing the issue. Thanks for the workaround, @lokimckay

codernirdesh avatar Oct 30 '23 13:10 codernirdesh

thanks for your sample, and now i can get the ApexCharts, but when i use getChartByID, can get nothing here. and i check the apex id in chrome dev tool's elements tab, there is.

geminiyellow avatar Jan 10 '24 03:01 geminiyellow

This solution does work for me (NextJs 14.1 app router) for Timeline charts, but unfortunately not for Scatter plots. They do not render at all.

vincenzodomina avatar Jul 03 '24 14:07 vincenzodomina