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

Next.js 15 broken renderToStream

Open frontBOI opened this issue 11 months ago • 13 comments
trafficstars

My code runs on a Next.js 15 API route, so in a Node environment. I get the same error as in this issue:

Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7B%24%24typeof%2C%20type%2C%20key%2C%20props%2C%20_owner%2C%20_store%7D&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

Everything worked before I switched to Next.js 15.

To Reproduce Simply create a custom Next.js API route and paste this code:

import ReactPDF from '@react-pdf/renderer'

export async function POST() {
    const MyDocument = () => (
          <Document>
            <Page>
              <Text>React-pdf</Text>
            </Page>
          </Document>
        );
    
    const readStream = await ReactPDF.renderToStream(<MyDocument />);

    // ...
}

Expected behavior I shouldn't get an error thrown at me during this process.

Desktop (please complete the following information):

  • OS: macOS
  • Browser: chrome
  • React-pdf version: 4.1.5

frontBOI avatar Dec 04 '24 21:12 frontBOI

This error also happens on an Express server running on nodejs 20.17.0. Here is the code of the server:

import ReactPDF from '@react-pdf/renderer'

import { nodeStreamToBuffer } from './lib'

import bodyParser from 'body-parser'
import express from 'express'

const app = express()

app.use(bodyParser.json())

const port = 6969

app.post('/generate-pdf', async (req, res) => {
  try {
    // PDFComponent is a <Document/> I get from my Next.js 15 app, which is a valid ReactPDF Document
    const { PDFcomponent } = req.body

    const readStream = await ReactPDF.renderToStream(PDFcomponent)
    const buffer = await nodeStreamToBuffer(readStream)

    res.send(buffer)
  } catch (e: any) {
    console.error(e)
    res.status(500).send(e.message)
  }
})

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`)
})

This problem is critical because it blocks me in production, I can't revert to Next.js 14.

frontBOI avatar Dec 05 '24 10:12 frontBOI

Is this issue still unresolved? Last year I used this package for a system that is only used in December, but now the same system stops working. They still haven't detected the error? Is there any news?

leomerida15 avatar Dec 07 '24 22:12 leomerida15

@leomerida15 no, problem still unresolved, which is very problematic. Waiting for the team to prioritise this issue.

frontBOI avatar Dec 07 '24 23:12 frontBOI

@frontBOI bro, I have a temporary solution for you: freeze all versions of the dependencies to use versions from December 2023. This way it works for the backend in next.js. If you are not using functions from more current versions, I recommend doing this.

"resolutions":  {
	"@react-pdf/font":  "2.3.6",
	"@react-pdf/layout":  "3.6.2",
	"@react-pdf/pdfkit":  "3.0.2",
	"@react-pdf/primitives":  "3.0.0",
	"@react-pdf/render":  "3.2.6",
	"@react-pdf/types":  "2.3.3",
        "@react-pdf/textkit": "4.3.0"
},
"dependencies": {
	"@joshuajaco/react-pdf-renderer-bundled":  "3.1.12",
	"@react-pdf/renderer":  "3.3.0",
}

leomerida15 avatar Dec 08 '24 23:12 leomerida15

@frontBOI bro, I have a temporary solution for you: freeze all versions of the dependencies to use versions from December 2023. This way it works for the backend in next.js. If you are not using functions from more current versions, I recommend doing this.

"resolutions":  {
	"@react-pdf/font":  "2.3.6",
	"@react-pdf/layout":  "3.6.2",
	"@react-pdf/pdfkit":  "3.0.2",
	"@react-pdf/primitives":  "3.0.0",
	"@react-pdf/render":  "3.2.6",
	"@react-pdf/types":  "2.3.3",
        "@react-pdf/textkit": "4.3.0"
},
"dependencies": {
	"@joshuajaco/react-pdf-renderer-bundled":  "3.1.12",
	"@react-pdf/renderer":  "3.3.0",
}

Tried this, getting the following error:

⨯ [Error: Cannot find package '/<PATH>/web-app/node_modules/.pnpm/@[email protected][email protected]/node_modules/@react-pdf/primitives/lib/index.js' imported from /<PATH>/web-app/node_modules/.pnpm/@[email protected][email protected]/node_modules/@react-pdf/renderer/lib/react-pdf.js] {
  code: 'ERR_MODULE_NOT_FOUND',
  page: '/api/v1/invoices/create'
}

itaiperi avatar Dec 12 '24 21:12 itaiperi

This is still reproducible in the latest next version: 15.1.2.

Curstantine avatar Dec 21 '24 17:12 Curstantine

Figured out why exactly this happens on my project at least.

In a monorepo, my structure is as follows

apps -> app <- react 19 -> website <- react 19 -> extra

libs -> ui <- react version not specified -> etc

I noticed that under node_modules/@react-pdf/reconciler/node_modules/react/package.json it was using 18.3.1, in a react 19 context.

Logged isReact19 and it was returning false, because bun was installing react 18.3.1 for this specific package (more on why later)

https://github.com/diegomura/react-pdf/blob/master/packages/reconciler/src/index.js

/* eslint-disable import/extensions */
/* eslint-disable import/no-extraneous-dependencies */

import React from 'react';
import createRendererForReact19 from './reconciler-31.js';
import createRendererForReact18AndLess from './reconciler-23.js';

const isReact19 = React.version.startsWith('19');

export default isReact19
  ? createRendererForReact19
  : createRendererForReact18AndLess;

So I ran npm explain [email protected] and got a bunch of packages that were using it (and hence why it might've gotten confused). Bumped all my UI pacakges to latest (I use radix-ui), and boom, react was gone from the reconciler's node_modules folder.

In my case, some deep dependency, required react 18 image

Hope it helps :)

krzkz94 avatar Dec 22 '24 20:12 krzkz94

My code runs on a Next.js 15 API route, so in a Node environment. I get the same error as in this issue:

Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7B%24%24typeof%2C%20type%2C%20key%2C%20props%2C%20_owner%2C%20_store%7D&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

Everything worked before I switched to Next.js 15.

To Reproduce Simply create a custom Next.js API route and paste this code:

import ReactPDF from '@react-pdf/renderer'

export async function POST() {
    const MyDocument = () => (
          <Document>
            <Page>
              <Text>React-pdf</Text>
            </Page>
          </Document>
        );
    
    const readStream = await ReactPDF.renderToStream(<MyDocument />);

    // ...
}

Expected behavior I shouldn't get an error thrown at me during this process.

Desktop (please complete the following information):

  • OS: macOS
  • Browser: chrome
  • React-pdf version: 4.1.5

Have you found the solution for this?

xakieezx avatar Jan 04 '25 14:01 xakieezx

Figured out why exactly this happens on my project at least.

In a monorepo, my structure is as follows

apps -> app <- react 19 -> website <- react 19 -> extra

libs -> ui <- react version not specified -> etc

I noticed that under node_modules/@react-pdf/reconciler/node_modules/react/package.json it was using 18.3.1, in a react 19 context.

Logged isReact19 and it was returning false, because bun was installing react 18.3.1 for this specific package (more on why later)

https://github.com/diegomura/react-pdf/blob/master/packages/reconciler/src/index.js

/* eslint-disable import/extensions */
/* eslint-disable import/no-extraneous-dependencies */

import React from 'react';
import createRendererForReact19 from './reconciler-31.js';
import createRendererForReact18AndLess from './reconciler-23.js';

const isReact19 = React.version.startsWith('19');

export default isReact19
  ? createRendererForReact19
  : createRendererForReact18AndLess;

So I ran npm explain [email protected] and got a bunch of packages that were using it (and hence why it might've gotten confused). Bumped all my UI pacakges to latest (I use radix-ui), and boom, react was gone from the reconciler's node_modules folder.

In my case, some deep dependency, required react 18 image

Hope it helps :)

@krzkz94 did you manage to find a workaround after discovering this?

chrisui avatar Jan 24 '25 17:01 chrisui

Hey, yes, basically you need to make sure that the react version used in the package is the same as the one used in your host app

In my case, the package was using react 18 due to some other outdated package, updating all dependencies fixed the issue.

Commands to debug this are in my previous post (npm explain)

krzkz94 avatar Jan 24 '25 18:01 krzkz94

I'm still using React 18.3.1 with Next 15.3.0 and was able to use renderToStream by creating an api route in the pages/api directory.

fedescoinc avatar Apr 25 '25 10:04 fedescoinc

Any solution?

Andres6936 avatar Jun 09 '25 17:06 Andres6936

Any solution?

I resolve updating the dependency to 4.3.0 @react-pdf/renderer

Andres6936 avatar Jun 11 '25 16:06 Andres6936

Is the problem related to the Turbo Pack in Next15?

master-iot-freelancer avatar Aug 22 '25 07:08 master-iot-freelancer

I was able to fix this with running the below versions by switching for that single route to use page router

so I literally have the app folder

then the

pages with that one api route

"@react-pdf/renderer": "^4.3.0",
 "react": "^18.3.1",
 "next": "^15.5.3"

Luke-Markham avatar Sep 21 '25 20:09 Luke-Markham

I updated @react-pdf/rendere to 4.3.1 and it started working again. I'm using React 19.0 and NextJS 15.5.3.

guiflr avatar Oct 31 '25 18:10 guiflr