7

I want to use nivo with Next but when I load the page containing a pie chart made with nivo, I get this error: ReferenceError: ResizeObserver is not defined.

My Pie.js component:

import { ResponsivePie } from "@nivo/pie";

export const data = [
  {
    id: "c",
    label: "c",
    value: 80,
    color: "hsl(8, 70%, 50%)",
  },
  {
    id: "lisp",
    label: "lisp",
    value: 188,
    color: "hsl(122, 70%, 50%)",
  },

  {
    id: "go",
    label: "go",
    value: 161,
    color: "hsl(111, 70%, 50%)",
  },
];

export default function MyPie({ data }) {

    return (
        <ResponsivePie
            data={data}
            margin={{ top: 40, right: 80, bottom: 80, left: 80 }}
            innerRadius={0.5}
            padAngle={0.7}
            cornerRadius={3}
            activeOuterRadiusOffset={8}
            borderWidth={1}
            borderColor={{ from: "color", modifiers: [["darker", 0.2]] }}
            arcLinkLabelsSkipAngle={10}
            arcLinkLabelsTextColor="#333333"
            arcLinkLabelsThickness={2}
            arcLinkLabelsColor={{ from: "color" }}
            arcLabelsSkipAngle={10}
            arcLabelsTextColor={{ from: "color", modifiers: [["darker", 2]] }}
            defs={[
            {
                id: "dots",
                type: "patternDots",
                background: "inherit",
                color: "rgba(255, 255, 255, 0.3)",
                size: 4,
                padding: 1,
                stagger: true,
            },
            {
                id: "lines",
                type: "patternLines",
                background: "inherit",
                color: "rgba(255, 255, 255, 0.3)",
                rotation: -45,
                lineWidth: 6,
                spacing: 10,
            },
            ]}
        />
    )
};

My chart.js page:

import MyPie, { data } from "../components/Pie";

import homeStyles from "../styles/Home.module.css";

function Chart() {
  return (
    <div className={homeStyles.divchart}>
      <MyPie data={data}/>
    </div>
  );
};
export default Chart;

This error only appears when using ResponsivePie and not Pie. I also tried to make it work with a React project but though I don't get this error, Nothing seems to be displayed.

Edit:

After some investigations, it looks like there is something wrong with @nivo/core 0.79.0 dependency. We should open an issue on the GitHub repo. I made some changes to check whether it is caused by my version of Next.js but the bug occurs only with @nivo/core 0.79.0.

juliomalves
  • 42,130
  • 20
  • 150
  • 146
Quentin C
  • 307
  • 3
  • 13

2 Answers2

10

It turns out this was the result of a bug introduced in version 0.79.0, which was fixed in https://github.com/plouc/nivo/pull/1886.

You should update @nivo/core to 0.79.1.


It looks like @nivo/pie is not compatible with Next.js server-side rendering as it utilizes Web APIs (ResizeObserver).

To avoid importing MyPie (and subsequently ResponsivePie) on the server, you can dynamically import it on the client-side only using next/dynamic with ssr: false.

import dynamic from "next/dynamic";
import { data } from "../components/Pie";
import homeStyles from "../styles/Home.module.css";

const MyPie = dynamic(() => import("../components/Pie"), {
    ssr: false
})

function Chart() {
    return (
        <div className={homeStyles.divchart}>
            <MyPie data={data}/>
        </div>
    );
};

export default Chart;
juliomalves
  • 42,130
  • 20
  • 150
  • 146
  • 1
    Yet it works on **0.78.0** and according to the creator of this lib, it is fully server-side compliant. The error was happening with every type of chart (bar, pie, line, etc). Then I would suspect there is a bug in the last `@nivo/core` version unless `resizeObserver` is not used in older versions, which I do not believe – Quentin C Feb 15 '22 at 14:35
  • 2
    Then you're most likely correct, it's probably a bug introduced in `0.79.0`. Might be related to this unreleased fix: https://github.com/plouc/nivo/pull/1886. – juliomalves Feb 15 '22 at 19:38
  • 3
    That's it, I went on the discord server and he told me he was working on a fix – Quentin C Feb 17 '22 at 09:15
  • 1
    Great save using `dynamic` @juliomalves . – Chris Yeung Jun 07 '22 at 15:26
  • Was there any further update on this? I'm getting this issue with nivo/line, nextjs 12.1.6, and react 18.2. I see there isn't a nivo/core 79.1, only 79.0, unlike all the other packages that have 79.1 and nivo/core 79.0 doesn't support React 18. – Al Pal Jul 18 '22 at 15:25
  • @AlPal You're right, there doesn't seem to be a published version of `@nivo/core` that contains the fix I mentioned. I'd recommend reaching out to nivo maintainers directly on their GitHub repo: https://github.com/plouc/nivo/issues. – juliomalves Jul 18 '22 at 15:47
0

It's likely that code is being run on server side (SSR), and ResizeObserver doesn't exist there. You should try to make sure that your code only executes when on client side.

It's hard for me to tell you how as I don't know what your setup is. You can likely just add a check to only run that part of the code if ResizeObserver is defined.

I hope at least this points you in the right direction.

T. Short
  • 3,481
  • 14
  • 30
  • As far as I know, my pages are CSR and I don't use any `getServerProps()` nor `getStaticProps()` function. I tried running a fresh Next project and installing `@nivo/core`and `@nivo/pie` but the error keeps showing whereas I follow all the steps (except installing "nivo" since I trust the official docs and it is not working when `npm i nivo`) described here: https://learnjsx.com/category/4/posts/nextjs-nivo – Quentin C Feb 12 '22 at 11:00
  • Actually the problem occurs randomly – Quentin C Feb 12 '22 at 13:31
  • 1
    So I made an observation: I ran the server and used `Pie` instead of `ResponsivePie` and once the page was loaded, I changed my code to `ResponsivePie` which displayed the pie but if I refresh the page, I get the error back. I cannot explain this... – Quentin C Feb 12 '22 at 13:59