react-pdf: Unable to render in Next.js 13 app directory route handler
Describe the bug
Using renderToBuffer in a Next.js 13 app directory route handler throws: TypeError: ba.Component is not a constructor.
It works as expected when using a route handler inside of the pages directory instead.
full output
- warn ./node_modules/node-fetch/lib/index.js
Module not found: Can't resolve 'encoding' in '/Users/foo/react-pdf-nextjs/node_modules/node-fetch/lib'
Import trace for requested module:
./node_modules/node-fetch/lib/index.js
./node_modules/cross-fetch/dist/node-ponyfill.js
./node_modules/@react-pdf/font/lib/index.cjs.js
./node_modules/@react-pdf/renderer/lib/react-pdf.cjs.js
./src/app/api/app.pdf/route.tsx
- error TypeError: ba.Component is not a constructor
at $$$reconciler (webpack-internal:///(sc_server)/./node_modules/@react-pdf/renderer/lib/react-pdf.cjs.js:631:50)
at createRenderer (webpack-internal:///(sc_server)/./node_modules/@react-pdf/renderer/lib/react-pdf.cjs.js:3889:12)
at pdf (webpack-internal:///(sc_server)/./node_modules/@react-pdf/renderer/lib/react-pdf.cjs.js:3997:28)
at _callee$ (webpack-internal:///(sc_server)/./node_modules/@react-pdf/renderer/lib/react-pdf.cjs.js:4189:32)
at tryCatch (webpack-internal:///(sc_server)/./node_modules/@babel/runtime/helpers/regeneratorRuntime.js:36:25)
at Generator.eval (webpack-internal:///(sc_server)/./node_modules/@babel/runtime/helpers/regeneratorRuntime.js:120:30)
at Generator.eval [as next] (webpack-internal:///(sc_server)/./node_modules/@babel/runtime/helpers/regeneratorRuntime.js:64:29)
at asyncGeneratorStep (webpack-internal:///(sc_server)/./node_modules/@babel/runtime/helpers/asyncToGenerator.js:4:28)
at _next (webpack-internal:///(sc_server)/./node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:17)
at eval (webpack-internal:///(sc_server)/./node_modules/@babel/runtime/helpers/asyncToGenerator.js:27:13)
at new Promise (<anonymous>)
at eval (webpack-internal:///(sc_server)/./node_modules/@babel/runtime/helpers/asyncToGenerator.js:19:16)
at renderToStream (webpack-internal:///(sc_server)/./node_modules/@react-pdf/renderer/lib/react-pdf.cjs.js:4202:21)
at renderToBuffer (webpack-internal:///(sc_server)/./node_modules/@react-pdf/renderer/lib/react-pdf.cjs.js:4235:12)
at GET (webpack-internal:///(sc_server)/./src/app/api/app.pdf/route.tsx:14:93)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:265:43)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:111:36)
at NoopContextManager.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:360:30)
at ContextAPI.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:30:58)
at NoopTracer.startActiveSpan (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:953:34)
at ProxyTracer.startActiveSpan (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:993:36)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:100:107)
at NoopContextManager.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:360:30)
at ContextAPI.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:30:58)
at NextTracerImpl.trace (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:100:32)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:253:53)
at AsyncLocalStorage.run (node:async_hooks:330:14)
at Object.wrap (webpack-internal:///(sc_server)/./node_modules/next/dist/server/async-storage/static-generation-async-storage-wrapper.js:41:24)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:207:97)
at AsyncLocalStorage.run (node:async_hooks:330:14)
at Object.wrap (webpack-internal:///(sc_server)/./node_modules/next/dist/server/async-storage/request-async-storage-wrapper.js:77:24)
at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:206:75)
at AsyncLocalStorage.run (node:async_hooks:330:14)
at AppRouteRouteModule.execute (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:203:56)
at AppRouteRouteModule.handle (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:326:41)
at RouteHandlerManager.handle (/Users/foo/react-pdf-nextjs/node_modules/next/dist/server/future/route-handler-managers/route-handler-manager.js:28:29)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async doRender (/Users/foo/react-pdf-nextjs/node_modules/next/dist/server/base-server.js:996:38)
at async cacheEntry.responseCache.get.incrementalCache.incrementalCache (/Users/foo/react-pdf-nextjs/node_modules/next/dist/server/base-server.js:1182:28)
at async /Users/foo/react-pdf-nextjs/node_modules/next/dist/server/response-cache/index.js:99:36
To Reproduce
- Visit https://react-pdf-nextjs-issue.vercel.app/
- Click the “Download PDF from app directory” link and see it not working
- Click the “Download PDF from pages directory” link and see it working
The full reproduction code can be found here
Desktop (please complete the following information):
- OS: MacOS
- Browser: chrome
- React-pdf version: 3.1.12
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 26
- Comments: 24 (3 by maintainers)
Commits related to this issue
- feat!: bundle React to make it work with Next.js RSC environment Fixes #2350 Fixes #2460 This proposal bundles React with @react-pdf/renderer. The reason for that is Next.js replacing current React... — committed to wojtekmaj/diegomura-react-pdf by wojtekmaj 5 months ago
- feat!: bundle React to make it work with Next.js RSC environment Fixes #2350 Fixes #2460 This proposal bundles React with @react-pdf/renderer. The reason for that is Next.js replacing current React... — committed to wojtekmaj/diegomura-react-pdf by wojtekmaj 5 months ago
Utilizing @joshuajaco/react-pdf-renderer-bundled is effective, but it would be great if these issues were addressed in the official repository.
Adding this to next.config.js solves issue for me:
Fantastic! I think this issue can be pretty much closed thanks to the above.
The issue seems to be that next bundles everything in the app directory using “react-server” mode where react only exports a subset of its functionality . This subset does not include the
Componentexport whichreact-reconcilertries to access, leading to the above mentioned error.As a temporary workaround I’ve published a fork that prebundles react, circumventing the problematic behavior.
Fixed in Next.js 14.1.1-canary.32 (available tomorrow) 🎉
@charanjit-singh It is working for me.
@joshuajaco this is an issue of Next.js 13 or React? I wish we can mentioned the fork in the quick start guide to make it clear to the developers developing Next.js application.
and this should be mentioned in the documentation?
The reason you’re getting
ba.Component()is not a constructor is because Next.js opted for a (ridiculous) decision to transparently replace your version of React with18.3.0-canary-8c8ee9ee6-20231026(sic!!!) if you happen to use App Router. This version notably missedReact.Component.To fix this issue on our side, without bundling React, we would need to drop
react-reconcilerdependency altogether or… update it to0.30.0-canary, but this brings in a couple of breaking changes we would need to deal with.I made
@react-pdf/rendererworks on app route page adding'use client'on top of page and adding@react-pdf/renderertotranspilePackagesinnext.config.jsAny updates yet?
Any luck addressing this issue?
next 14.2 is out now, seems like rendering pdf in app-folder route works out of the box 🎉
Getting this error when I try to include a image in a PDF and it work fine with
@joshuajaco/react-pdf-renderer-bundled. Not sure which other packages need to be included in theserverComponentsExternalPackagesWill this be solved?
Didn’t work
I have created page api, in Next Js even when you use App Router you can create Page Api Folder and there it works.
pages/api/ - it’s my solution even in App Router