react-pdf-charts icon indicating copy to clipboard operation
react-pdf-charts copied to clipboard

Next.js App Router react-dom server error

Open rodrgds opened this issue 2 years ago • 9 comments

Describe the bug

I'm getting the following error when I try to render a chart using ReactPDFChart in Next.js:

ReactServerComponentsError:

You're importing a component that imports react-dom/server. To fix it, render or return the content directly as a Server Component instead for perf and security.
Learn more: https://nextjs.org/docs/getting-started/react-essentials

The error was caused by importing 'react-pdf-charts/dist/index.js' in './pdfs/report.tsx'.

Versions:

"next": "13.4.8",
"@joshuajaco/react-pdf-renderer-bundled": "^3.1.12",
"recharts": "^2.8.0",
"react-pdf-charts": "^0.2.1",

I am also using @joshuajaco/react-pdf-renderer-bundled instead of regular react-pdf because of another bug with Next.js. I'm unsure of whether that has any implications on this particular case.

Reproduction

Using some chart, for example:

pdfs/report.tsx

...
  <ReactPDFChart>
    <PieChart width={500} height={300}>
      <Pie
        data={data}
        dataKey="value"
        nameKey="name"
        cx="50%"
        cy="50%"
        outerRadius={80}
        fill="#8884d8"
        label
      >
        {data.map((entry, index) => (
          <Cell
            key={`cell-${index}`}
            fill={COLORS[index % COLORS.length]}
          />
        ))}
      </Pie>
      <Legend />
    </PieChart>
  </ReactPDFChart>
...

This is how I render it and return it to the client, on a route.jsx API "page" (which worked without the charts):

some-api/route.jsx

const pdfBuffer = await renderToBuffer(
  <ReportPDF
    assessmentData={assessmentDataJson}
    companyData={companyDataJson}
    userStats={newUserStats}
    stats={stats}
  />
);

return new Response(pdfBuffer, {
  headers: {
    "Content-Type": "application/pdf",
    "Content-Disposition": `attachment; filename="invoice.pdf"`,
  },
});

Validations

rodrgds avatar Oct 11 '23 14:10 rodrgds

Does it work if you add use client on the file which imports react-pdf-charts?

EvHaus avatar Oct 12 '23 02:10 EvHaus

It doesn't. It now displays a different error:

Error: Attempted to call the default export of /home/kraktoos/dev/abc/pdfs/report.tsx from the server but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.

rodrgds avatar Oct 15 '23 10:10 rodrgds

I was able to get around the ReactServerComponentsError by using experimental.serverComponentsExternalPackages, but recharts is now failing to render on the server because it's using some client code that Next 14 can't run in a route handler. 😠

Here's where I got to: https://stackblitz.com/edit/stackblitz-starters-zt49kv?file=package.json

It currently fails with:

TypeError: Super expression must either be null or a function
node_modules/react-smooth/es6/Animate.js (19:112)
node_modules/react-smooth/es6/Animate.js (34:2)
node_modules/react-smooth/es6/Animate.js (314:2)

UPDATE: Unfortunately Next 14.2 still has the same issue. Here's a repo to reproduce the issue: https://github.com/EvHaus/react-pdf-charts-next-14

EvHaus avatar Feb 01 '24 07:02 EvHaus

I was able to get around the ReactServerComponentsError by using experimental.serverComponentsExternalPackages, but recharts is now failing to render on the server because it's using some client code that Next 14 can't run in a route handler. 😠

Here's where I got to: https://stackblitz.com/edit/stackblitz-starters-zt49kv?file=package.json

It currently fails with:

TypeError: Super expression must either be null or a function
node_modules/react-smooth/es6/Animate.js (19:112)
node_modules/react-smooth/es6/Animate.js (34:2)
node_modules/react-smooth/es6/Animate.js (314:2)

Hi,

Have you ever found the solution to this problem? I have a couple charts that I need to render into a PDF in a route handler. This seems like the most elegant option, but I am stuck on the Animate.js issue.

dominik-juriga avatar Mar 05 '24 15:03 dominik-juriga

I am getting this issue "Module not found: Error: Can't resolve 'react/jsx-runtime" and "Module not found: Error: Can't resolve 'react-dom/server" in react app where my react and react-dom both are pointing to version 17. How can I resolve it

poojas10 avatar Apr 03 '24 10:04 poojas10

I don't know how to resolve it. It seems to be a bug (or limitation of) Next.js. I've opened an issue with them here. Feel free to upvote it to raise its priority.

EvHaus avatar Apr 04 '24 06:04 EvHaus

I don't know how to resolve it. It seems to be a bug (or limitation of) Next.js. I've opened an issue with them here. Feel free to upvote it to raise its priority.

I am not using nextjs I have a react app with version 17 but I am getting the same error

poojas10 avatar Apr 04 '24 10:04 poojas10

Can you please create a repo with your setup and share it with me? I can take a look.

EvHaus avatar Apr 04 '24 14:04 EvHaus

You probably do not want to use any serverside rendering for libs like react-pdf and react-pdf-charts. I have yet to get it to work.

In my experience you only want to execute this code in the browser (client-side), not to be confused with "use client". Client components in Next.js still get prerendered on the server (docs)

For loading components client-side without SSR there is next/dynamic (docs)

import dynamic from 'next/dynamic';

const AnalyticsPDF = dynamic(() => import('../pdf/analytics-pdf'), {
    ssr: false,
});

const Viewer = ({ customer }: Props) => {
    return <AnalyticsPDF customer={customer} />;
}

Hope this helps!

Willem-Jaap avatar Feb 21 '25 14:02 Willem-Jaap