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

Can't resolve 'pdfjs-dist/build/pdf.worker.min.mjs in Nextjs 14 app router

Open raibann opened this issue 1 year ago • 5 comments

Before you start - checklist

  • [X] I followed instructions in documentation written for my React-PDF version
  • [X] I have checked if this bug is not already reported
  • [X] I have checked if an issue is not listed in Known issues
  • [X] If I have a problem with PDF rendering, I checked if my PDF renders properly in PDF.js demo

Description

import { Box, CircularProgress, Pagination, Stack, Typography } from '@mui/material'; import React, { useState } from 'react'; import { DocumentText } from 'iconsax-react'; import 'react-pdf/dist/esm/Page/AnnotationLayer.css'; import 'react-pdf/dist/esm/Page/TextLayer.css'; import { Document, Page, pdfjs } from 'react-pdf'; pdfjs.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();

const options = { cMapUrl: '/cmaps/', standardFontDataUrl: '/standard_fonts/', };

/**

  • Comp / const CustPreviewPdf = ({ file, disablePage }: { file?: File | string; disablePage?: boolean }) => { /*
    • States */ const [totalPages, setTotalPages] = useState(0); const [pageNumber, setPageNumber] = useState(1);

/**

  • Methods */ const onDocumentLoadSuccess = ({ totalPages }: { totalPages: number }) => { setTotalPages(totalPages); }; return ( <> <Document file={file} onLoadSuccess={(value) => onDocumentLoadSuccess({ totalPages: value.numPages })} loading={<CircularProgress />} noData={ <Stack direction={'column'} alignItems={'center'}> <DocumentText size={24} /> <Typography variant='subtitle2'>No PDF Imported</Typography> </Stack> } className={'disable-pdf-select'} options={options}
    {!disablePage && ( , page: number) => { setPageNumber(page); }} /> )}
</>

); };

export default CustPreviewPdf;

Steps to reproduce

                                                                                           ^^^^^^
`----

Caused by: 0: failed to parse input file 1: Syntax Error

Build failed because of webpack errors when I install react pdf version 9.1.0 it can't build.

Expected behavior

⨯ node_modules/pdfjs-dist/build/pdf.mjs (5448:0) @ eval ⨯ TypeError: Promise.withResolvers is not a function at webpack_require (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/webpack-runtime.js:33:43) at eval (./src/components/customs/media/CustPreviewPdf.tsx:17:67) at (ssr)/./src/components/customs/media/CustPreviewPdf.tsx (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/app/new-document/page.js:642:1) at webpack_require (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/webpack-runtime.js:33:43) at eval (./src/app/new-document/components/qrcode/index.tsx:13:98) at (ssr)/./src/app/new-document/components/qrcode/index.tsx (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/app/new-document/page.js:433:1) at webpack_require (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/webpack-runtime.js:33:43) at eval (./src/app/new-document/page.tsx:27:76) at (ssr)/./src/app/new-document/page.tsx (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/app/new-document/page.js:543:1) at webpack_require (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/webpack-runtime.js:33:43) at JSON.parse () null

Actual behavior

Additional information

Environment

  • Browser (if applicable):
  • React-PDF version:
  • React version:
  • Bundler name and version (if applicable):

raibann avatar Aug 13 '24 09:08 raibann

Same here it throws an error and the PDF is not rendered:

image

orlando-aidora avatar Aug 13 '24 21:08 orlando-aidora

this worked for me

UmairJibran avatar Aug 18 '24 08:08 UmairJibran

Check out this as well! Bun patch fixed it for me :D

https://github.com/vercel/next.js/issues/65406#issuecomment-2295783162

https://bun.sh/docs/install/patch

kristianeboe avatar Aug 27 '24 20:08 kristianeboe

I encountered the same error when using react-pdf in my Next.js (version 14) app during the build phase. It was working perfectly in development, but the error appeared during the production build.

WhatsApp Image 2024-08-29 at 10 59 42 PM

@UmairJibran made a valid point, and while his solution might work for some, it didn't solve the issue for me. I fixed by replacing the following line:

 pdfjs.GlobalWorkerOptions.workerSrc = new URL(
   'pdfjs-dist/build/pdf.worker.min.mjs',
   import.meta.url,
 ).toString();

with this

pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;

I switched to using the CDN, as specified in the docs

Here is the screenshot

WhatsApp Image 2024-08-29 at 10 57 40 PM

satyadalei avatar Aug 29 '24 17:08 satyadalei

I've encountered the same error too.

Building on top of @satyadalei's solution.

You can download the CDN and put it in the public directory and call it like this.

import { Document, Page, pdfjs } from 'react-pdf'

pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.mjs

Additionally, you might run into this error [ERROR] Promise.withResolvers is not a function Stack trace:

So, you have to add the polyfill

// Polyfill
// NOTE: pdfjs-dist is throwing Promise.withResolvers is not a function
// This is a workaround to fix the issue
if (typeof Promise.withResolvers !== 'function') {
Promise.withResolvers = function <T>() {
  let resolve!: (value: T | PromiseLike<T>) => void
  let reject!: (reason?: any) => void
  const promise = new Promise<T>((res, rej) => {
    resolve = res
    reject = rej
  })
  return { promise, resolve, reject }
}
}

export {}

Make sure to declare the type in your declaration.d.ts

interface PromiseConstructor {
 withResolvers<T>(): {
   promise: Promise<T>
   resolve: (value: T | PromiseLike<T>) => void
   reject: (reason?: any) => void
 }
}

Your component should look something like this

import 'path/to/polyfill'
import { Document, Page, pdfjs } from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.mjs'

scaabel avatar Sep 05 '24 23:09 scaabel

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this issue will be closed in 14 days.

github-actions[bot] avatar Dec 09 '24 00:12 github-actions[bot]

This issue was closed because it has been stalled for 14 days with no activity.

github-actions[bot] avatar Dec 30 '24 00:12 github-actions[bot]

import {  GlobalWorkerOptions } from "pdfjs-dist";

GlobalWorkerOptions.workerSrc = new URL(
  "pdfjs-dist/build/pdf.worker.min.mjs",
  import.meta.url
).toString();

AbdelrahmanAbounida avatar Jan 17 '25 13:01 AbdelrahmanAbounida

import {  GlobalWorkerOptions } from "pdfjs-dist";

GlobalWorkerOptions.workerSrc = new URL(
  "pdfjs-dist/build/pdf.worker.min.mjs",
  import.meta.url
).toString();

@AbdelrahmanAbounida This worked for me. Thank you!

gianluca-romeo-levels avatar Jan 22 '25 09:01 gianluca-romeo-levels

@AbdelrahmanAbounida thanks a ton. I was stuck on this for FOREVER and none of the above solutions worked..

Ckle avatar Feb 05 '25 17:02 Ckle

I'm using NextJS 14, and the way this worked for me was to import the worker first, as I was getting errors saying:

Module not found: ESM packages (pdfjs-dist/build/pdf.worker.min.mjs) need to be imported. Use 'import' to reference the package instead. https://nextjs.org/docs/messages/import-esm-externals

So I imported it like this:

import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.min.mjs'
import { Document, Page, pdfjs } from 'react-pdf'

pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  pdfjsWorker,
  import.meta.url
).toString()

And now it works.

Note: I am getting a TypeScript error when importing pdfjsWorker. I've already added @types/pdfjs-dist but that didn't solve the issue.

cynicalsubject avatar Feb 12 '25 20:02 cynicalsubject

Thanks @cynicalsubject only your solution worked for me. Lost 2 hours at this : / . And yes, Typescript is raising an error (using Next 15)

GreenFlag31 avatar Feb 15 '25 15:02 GreenFlag31

For those who are using webpack, you only need to import

import 'pdfjs-dist/build/pdf.worker.min.mjs'

It does not have a default export so we do not have to use this on pdfjs.GlobalWorkerOptions.workerSrc

I am not sure why it works tho

rabrenio avatar Feb 20 '25 03:02 rabrenio

For me any of the above will always get when deploying it to server.(It works on local build and dev...)

Error occurred prerendering page "/my-pdf-page". Read more: https://nextjs.org/docs/messages/prerender-error

TypeError: Promise.withResolvers is not a function

So the solution I have done is to totally make the component client side render by adding dynamic.

// page.tsx

import dynamic from "next/dynamic";
const CSR = dynamic(() => import("./path/to/component"), {
  ssr: false,
});

And remember to add "use client" in the component as well.

jimmy-chiang avatar Feb 23 '25 09:02 jimmy-chiang

If you're using pdfjs-dist in a TypeScript project and facing type issues, follow these steps:

  1. Install pdfjs-dist
    Run this command to install it:
    npm i pdfjs-dist

  2. Import pdfjs-dist
    In your code, import it like this:
    import * as pdfjsLib from "pdfjs-dist/webpack";

  3. Fix TypeScript Errors
    TypeScript may not recognize pdfjs-dist/webpack. To fix this, create a type declaration file:

  • Go to src/types/ (create the types folder if it doesn’t exist).
  • Inside it, create a file named pdfjs.d.ts.
  • Add the following code to pdfjs.d.ts:
    declare module "pdfjs-dist/webpack" { import pdfjs from "pdfjs-dist"; export = pdfjs; }

#### 4. Done!  
Now TypeScript will recognize `pdfjs-dist/webpack`, and you can use it without errors.

Sabarish76 avatar Mar 12 '25 07:03 Sabarish76

If you're using pdfjs-dist in a TypeScript project and facing type issues, follow these steps:

  1. Install pdfjs-dist Run this command to install it: npm i pdfjs-dist
  2. Import pdfjs-dist In your code, import it like this: import * as pdfjsLib from "pdfjs-dist/webpack";
  3. Fix TypeScript Errors TypeScript may not recognize pdfjs-dist/webpack. To fix this, create a type declaration file:
  • Go to src/types/ (create the types folder if it doesn’t exist).
  • Inside it, create a file named pdfjs.d.ts.
  • Add the following code to pdfjs.d.ts: declare module "pdfjs-dist/webpack" { import pdfjs from "pdfjs-dist"; export = pdfjs; }

#### 4. Done!  
Now TypeScript will recognize `pdfjs-dist/webpack`, and you can use it without errors.

Thank you @Sabarish76 ❤️

adamorlowski-cf avatar May 27 '25 08:05 adamorlowski-cf

this worked for me

 pnpm add pdfjs-dist 

or

npm install  pdfjs-dist 
"use client"
import * as pdfjs from "pdfjs-dist";

pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  "pdfjs-dist/build/pdf.worker.min.mjs",
  import.meta.url
).toString();

muneebpeerzade avatar Aug 07 '25 12:08 muneebpeerzade