react-pdf: Failed to load PDF file

i am having trouble showing pdf file tried every way from importing as file and directory giving path it is giving an error Failed to load PDF file. And When I am using webpack or parcel it just showing loading PDF.

Code

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { Document, Page } from 'react-pdf'
import lesson2 from './lesson2.pdf'
class App extends Component {
  state = { numPages: null, pageNumber: 1 };

  onDocumentLoadSuccess = ({ numPages }) => {
    this.setState({ numPages });
  };

  goToPrevPage = () =>
    this.setState(state => ({ pageNumber: state.pageNumber - 1 }));
  goToNextPage = () =>
    this.setState(state => ({ pageNumber: state.pageNumber + 1 }));

  render() {
    const { pageNumber, numPages } = this.state;

    return (
      <div>
        <nav>
          <button onClick={this.goToPrevPage}>Prev</button>
          <button onClick={this.goToNextPage}>Next</button>
        </nav>

        <div style={{ width: 600 }}>
          <Document
            file={lesson2}
            onLoadSuccess={this.onDocumentLoadSuccess}
          >
            <Page pageNumber={pageNumber} width={600} />
          </Document>
        </div>

        <p>
          Page {pageNumber} of {numPages}
        </p>
      </div>
    );
  }
}

export default App;

Folder Structure

capture1

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 40 (11 by maintainers)

Commits related to this issue

Most upvoted comments

@saadpasta @MichaelBlanchet I reckon you are using create-react-app as a boilerplate ?

Add/change these to your code

import { Document, Page, pdfjs } from "react-pdf";
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

as instructed on the main page of this project. Also make sure pdf file is to be found for your project (public directory)

I have a very similar (simple) App.js - as per your description - and not able to load a PDF document. Getting the following errors:

Uncaught SyntaxError: Unexpected token <
index.js:1452 
Error: Setting up fake worker failed: "Cannot read property 'WorkerMessageHandler' of undefined".
    at pdf.js:10999
function.console.(anonymous function) @ index.js:1452
consoleOnDev @ utils.js:188
errorOnDev @ utils.js:207
(anonymous) @ Document.js:291
_callee$ @ Document.js:229
tryCatch @ runtime.js:62
invoke @ runtime.js:288
prototype.(anonymous function) @ runtime.js:114
asyncGeneratorStep @ asyncToGenerator.js:3
_throw @ asyncToGenerator.js:29
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js:13
_next @ asyncToGenerator.js:25
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js:13
_next @ asyncToGenerator.js:25
(anonymous) @ asyncToGenerator.js:32
(anonymous) @ asyncToGenerator.js:21
componentDidMount @ Document.js:435
commitLifeCycles @ react-dom.development.js:16722
commitAllLifeCycles @ react-dom.development.js:18160
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
commitRoot @ react-dom.development.js:18365
completeRoot @ react-dom.development.js:19894
performWorkOnRoot @ react-dom.development.js:19817
performWork @ react-dom.development.js:19722
performSyncWork @ react-dom.development.js:19696
requestWork @ react-dom.development.js:19551
scheduleWork @ react-dom.development.js:19358
scheduleRootUpdate @ react-dom.development.js:20062
updateContainerAtExpirationTime @ react-dom.development.js:20088
updateContainer @ react-dom.development.js:20156
push../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render @ react-dom.development.js:20435
(anonymous) @ react-dom.development.js:20589
unbatchedUpdates @ react-dom.development.js:19939
legacyRenderSubtreeIntoContainer @ react-dom.development.js:20585
render @ react-dom.development.js:20652
./src/index.js @ index.js:7
__webpack_require__ @ bootstrap:782
fn @ bootstrap:150
0 @ serviceWorker.js:135
__webpack_require__ @ bootstrap:782
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
4

webpackHotDevClient.js:120 ./node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

Using https in front of the url seems to resolve the problem for me:

pdfjs.GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

Note: This comment previously said that we can totally do what pdf-viewer-reactjs is doing, which was technically true, but here’s why you shouldn’t:

In pdf-viewer-reactjs, they import Worker like this:

import pdfjs from 'pdfjs-dist'
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'

pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;

Unfortunately, this module exports nothing and consequently works as if you didn’t set workerSrc at all. This is invalid, causes an error and a “fake” worker to be loaded. This is a behavior that’s no longer supported because of performance issues that loading “fake” worker causes and is highly discouraged by pdf.js team.

import React, { PureComponent } from 'react'
import { Document, Page, pdfjs } from 'react-pdf';
...
pdfjs.GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

export default class PDFView extends PureComponent {
  ...
}

works well for me.

@ajbee07

If you’re using craco, you can add a webpack rule to create the worker as a separate chunk. Then you can import it and assign it to workerSrc, and avoid using a CDN-hosted version.

// craco.config.js
module.exports = {
    webpack: {
        configure: {
            module: {
                rules: [
                    {
                        test: /pdf\.worker\.js/,
                        loader: "file-loader",
                        options: {
                            name: "static/js/[name].[hash:8].[ext]",
                        },
                    },
                ],
            },
        },
    },
};
import { Document, Page, pdfjs } from "react-pdf";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker";

pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;

For these that use CRA, and do not want to use CDN, as is my case, you can perform following steps:

  1. Create script within package.json: “copy-pdfjs-worker” : “cp ./node_modules/pdfjs-dist/build/pdf.worker.js public/scripts” Here we copy from node modules into public/scripts folder. During the build this folder would be copied into build folder. This script is manually triggered.

  2. And register it as follows: pdfjs.GlobalWorkerOptions.workerSrc = ${process.env.PUBLIC_URL}/scripts/pdf.worker.js;

This solution would work for both npm build and npm start commands (CRA already existing scripts).

Hope this command helps someone. In create-react-app, the instructions for this libs say:

you will have to make sure on your own that pdf.worker.js file from pdfjs-dist/build is copied to your project’s output folder.

If your build process uses cli commands, (i.e. aws buildspec), you can use this:

mkdir -p build && cp ./node_modules/pdfjs-dist/build/pdf.worker.js build

I had similar issue, in my case it was incorrect file to be loaded

const path = './data/sample.pdf'

in my localhost dev the path was calculated relative to the current route not the root, but local web server instead of responding with 404 it was returning the index.html content which couldnt be parsed 😃

In the network tab it was showing as sample.pdf which was confusing, but looking at response content disclosed that it was in fact a web page not PDF.

When I’ve modified the path to be as const path = '/data/sample.pdf' it all started to work.

  1. Check the console for errors
  2. Plug in to onLoadError with onLoadError={console.error} to see additional messages
  3. Check Network tab of devtools to ensure that PDF.js downloads the worker file from a correct URL

Failed to open PDF fixed, but now it’s showing InvalidPDFException: InvalidPDFException {message: “Invalid PDF structure.”, name: “InvalidPDFException”} Anyone knows how to fix it??

@saadpasta @MichaelBlanchet I reckon you are using create-react-app as a boilerplate ?

Add/change these to your code

import { Document, Page, pdfjs } from "react-pdf";
 pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

as instructed on the main page of this project. Also make sure pdf file is to be found for your project (public directory)

I see that using componentDidMount() { pdfjs.GlobalWorkerOptions.workerSrc = //cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js; }

resolved the issue: “Failed to load PDF file.”

@MichaelBlanchet

Uncaught SyntaxError: Unexpected token <

See #52

@saadpasta @MichaelBlanchet I reckon you are using create-react-app as a boilerplate ?

Add/change these to your code

import { Document, Page, pdfjs } from "react-pdf";
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

as instructed on the main page of this project. Also make sure pdf file is to be found for your project (public directory)

This worked for me. The issue occurred with the Codesandbox react typescript template.

@jzskca I actually love your solution here. Experimented with it in #756.

I think after the changes create-react-app should be able to use webpack specific entry file just fine.

Please kindly check react-pdf v5.3.0-beta.2 and let me know how it goes!

@pwhipp You do need workers - PDF.js no longer works properly without them, so neither does React-PDF. If you don’t want to use external worker, you can also manually copy PDF.js worker to your build folder & set pdfjs.GlobalWorkerOptions.workerSrc to point at it.