react-pdf is not working when build with nextjs

Created on 23 Jan 2018  路  12Comments  路  Source: wojtekmaj/react-pdf

It's working fine on development mode with nextjs. However when I build my nextjs app, it gives me an error that worker.js is not found(404). It looks that *.worker.js is existed in .next director.
next bundle
Can you point me to a way to resolve it.

Thanks for your time.

404 not found

help wanted question

Most helpful comment

FYI for others using Next.js they have a helper that we used to work around this issue.

Our problem was that rendering anything which depends on PDF.js server-side will throw errors, as the library itself contains browser API calls which are not safe in Node. By using the above helper to import the component that handles PDF rendering we were able to defer parsing of the library code to the browser, where it ran without error:

// This is our wrapper component which contains the PDF viewer
const PDFViewer = dynamic(import('../../components/PDFViewer'), { ssr: false });

class ExampleClass extends Component {
  render() {
    return (
      <div>
        <PDFViewer />
      </div>
    );
  }
}

All 12 comments

Hello @nyamba,
I'm not actively supporting nextjs as I don't have all the necessary knowledge. I can only give you one hint:

You can manually set workerSrc path to whatever path you like, so if you define where the worker file should be copied to (hint 2: it does not need building, it can be safely just copied from pdfjs-dist node_module) and how it's called, then your problem is solved entirely.

You could also do the opposite thing, meaning - looking where React-PDF looks for worker file and ensure your bundling process puts it there. But the first option is a safer bet :)

FYI for others using Next.js they have a helper that we used to work around this issue.

Our problem was that rendering anything which depends on PDF.js server-side will throw errors, as the library itself contains browser API calls which are not safe in Node. By using the above helper to import the component that handles PDF rendering we were able to defer parsing of the library code to the browser, where it ran without error:

// This is our wrapper component which contains the PDF viewer
const PDFViewer = dynamic(import('../../components/PDFViewer'), { ssr: false });

class ExampleClass extends Component {
  render() {
    return (
      <div>
        <PDFViewer />
      </div>
    );
  }
}

I was facing this problem for a long time in a nextJs production environment: __next[hash].worker.js not found on custom server.

Both provided solutions with custom setOptions method or dynamic import didn't work for me.
So I dedided to work without worker.

```
/* next.config.js : webpack extension */
webpack: (config) => {

/* PdfViewer : override defaults aliases */

config.resolve.alias = Object.assign({}, config.resolve.alias, {
  "react-pdf": "react-pdf/dist/entry.noworker.js"
});

return config;

}
```

I don't know if it's recommended, but it now works in production.

I see nothing wrong with this code, apart from the fact it won't work with React-PDF 4.x, since there's no longer an option to run React-PDF without a Worker. All browsers should be capable of running the worker though, so you should aim to enable it if possible.

I am also using next.js and have the same issue, I tried many suggestions and workarounds but failed.

I ended up using this module without worker.

I cannot reproduce the issue with:

    "next": "9.1.4",
    "react": "16.12.0",

This works just fine for me:

import React from "react";
import { Document, Page } from "react-pdf";


class Test extends React.Component {
  render() {
    return (
      <Document
        file={{
          url: "./my.pdf"
        }}
        onLoadError={e =>
          console.log("Error while loading document! " + e.message)
        }
        onSourceError={e =>
          console.log("Error while loading document! " + e.message)
        }
      >
        <Page pageNumber={1} />
      </Document>
    );
  }
}

const index = () => {
  return (
    <div>
      <Test></Test>
    </div>
  );
};

export default index;

@feluxe

the issue happens when trying to use the service worker implementation, which is supposed to be imported like this: import { Document } from 'react-pdf/dist/esm/entry.webpack';

somewhat related... @wojtekmaj , I'm not seeing the esm or umd directories. I'm using version 4.1.0. I tried importing from react-pdf/dist/entry.webpack, which does exist. I'm getting the error about not finding __next/[hash].worker.js so I'm going to try using version 3.x and the entry.noworker.js file

@RyanDriscoll You're looking at docs for the newer version of React-PDF than you're currently using. Read the docs for 4.1.0 here: https://github.com/wojtekmaj/react-pdf/tree/v4.1.0

Have tried this on Next v9 stack and React-PDF v4.1 alongside @felizuno's Dynamic Import patch.

import { Document, Page } from 'react-pdf/dist/entry.webpack'

However, the PDF gets stuck in loading forever. How to get the webpack working with NextJS?

Have also tried to install Next Workers to no avail. (Still loading)

@wojtekmaj , I'm not seeing the esm or umd directories. I'm using version 4.1.0.

You're looking at React-PDF 5.0 docs.

@wojtekmaj thanks for this.. I looking for pdf to image. can this library will help me out or anything ?

In case anyone comes here looking for NextJs implementation...I got it to work just fine with the below (an amalgamation of all the comments above; thanks all):

Install as per documentation:
npm install react-pdf

NB: ensure you don't already have pdfjs-dist installed, as the version you installed may mismatch this package.

Create a wrapped component, as per documentation:

import React from 'react';

import {
  Document, Page,
} from 'react-pdf/dist/esm/entry.webpack';

const PdfViewer = ({
  url, width, pageNumber
}) => (
  <Document file={url}>
    <Page
      pageNumber={pageNumber}
      width={width}
    />
  </Document>
);

export default PdfViewer;

Import dynamically, as SSR FALSE:

import React from 'react';

import dynamic from 'next/dynamic';

const PdfViewer = dynamic(
  () => import('./PdfViewer'),
  { ssr: false }
);

This will ensure that the correct version of pdf.js is pulled in from this react-pdf package, and Next/webpack does the rest.

Was this page helpful?
5 / 5 - 1 ratings

Related issues

zambony picture zambony  路  3Comments

Crackiii picture Crackiii  路  3Comments

shivekkhurana picture shivekkhurana  路  4Comments

SandMoshi picture SandMoshi  路  3Comments

douglasrcjames picture douglasrcjames  路  4Comments