Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to load PDF file #321

Closed
saadpasta opened this issue Dec 12, 2018 · 43 comments
Closed

Failed to load PDF file #321

saadpasta opened this issue Dec 12, 2018 · 43 comments
Assignees
Labels
question Further information is requested

Comments

@saadpasta
Copy link

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

@wojtekmaj
Copy link
Owner

  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

@wojtekmaj wojtekmaj self-assigned this Dec 13, 2018
@wojtekmaj wojtekmaj added the question Further information is requested label Dec 13, 2018
@wojtekmaj wojtekmaj changed the title Failed to load PDF file (checked every way possible) Failed to load PDF file Dec 14, 2018
@MichaelBlanchet
Copy link

MichaelBlanchet commented Dec 18, 2018

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

@pxFIN
Copy link
Contributor

pxFIN commented Jan 3, 2019

@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)

@wojtekmaj
Copy link
Owner

@MichaelBlanchet

Uncaught SyntaxError: Unexpected token <

See #52

@LukaszGrela
Copy link

LukaszGrela commented Feb 13, 2019

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.

@jtibrewal09
Copy link

Error: Setting up fake worker failed: "Cannot read property 'WorkerMessageHandler' of undefined".

link to codesandbox.
https://codesandbox.io/s/kkq9zv96jo

@wojtekmaj
Copy link
Owner

@jtibrewal09 #52 might help you, sounds like a worker issue.

@wojtekmaj
Copy link
Owner

I'm closing this issue to give other issues more visibility. If you still need assistance with this matter, please do not hesitate to reply and I'll reopen.

Happy coding!

@gundojuprashanth
Copy link

Hi
I have issue in loading pdf. Its just showing Loading PDF.
Screenshot (40)

@turetran
Copy link

turetran commented Oct 20, 2019

@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."

@jhaanji035
Copy link

I am using base64 string, But still it says : "Setting up fake worker failed: "Loading chunk 0 failed"

@johndevedu
Copy link

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

@michaelkoelle
Copy link

michaelkoelle commented Dec 22, 2019

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`;

@maxlxq
Copy link

maxlxq commented Mar 13, 2020

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.

@pwhipp
Copy link

pwhipp commented Jun 16, 2020

Same problem. Two small pdfs that open fine in viewers. One hangs loading and the other (after adding onLoadError={console.error} switched from hanging on 'Loading PDF' to displaying "Failed to load PDF file" with

Warning: Setting up fake worker.
vendors~pdfjsWorker.js:3 Uncaught SyntaxError: Unexpected token '<'
2react_devtools_backend.js:6 Error: Setting up fake worker failed: "Loading chunk 0 failed.
(missing: http://localhost:8000/vendors~pdfjsWorker.js)".
    at main.js?ts=1592286747:81

in the console window. I don't need workers - the files are only a few MB each.

@wojtekmaj
Copy link
Owner

@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.

@pwhipp
Copy link

pwhipp commented Jun 22, 2020

Thanks. After many hours (webpack paths seem to make getting worker loading working properly crazy and I only need them to present a couple of little pdfs) I gave up and used the simpler but more limited https://github.com/ansu5555/pdf-viewer-reactjs.

I will come back to this if I have some other need that forces us to start using workers.

@wojtekmaj
Copy link
Owner

wojtekmaj commented Jun 26, 2020

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.

@pwhipp
Copy link

pwhipp commented Jun 29, 2020

Yes, thanks. They just did it out of the box.

@WildSaoFeng
Copy link

Thank you sooooo much for the solution! Same issue and same solution here!

rachOS added a commit to rachOS/portfolio-front that referenced this issue Aug 10, 2020
Display pdf in Contact.jsx ok!

==> display fixed with : pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
wojtekmaj/react-pdf#321 (comment)
@wojtekmaj
Copy link
Owner

wojtekmaj commented Aug 12, 2020

Sorry - I noticed something and had to edit my comment above. What ansu5555/pdf-viewer-reactjs is doing is actually wrong and will harm your application's performance.

@nevres
Copy link

nevres commented Aug 13, 2020

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).

@ajbee07
Copy link

ajbee07 commented Sep 24, 2020

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.

aside from importing via cdn and the solution of @nevres , is there other way to just simply import the worker?

@myfairshare
Copy link

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.

Thanks buddy, I was going crazy, this worked for me!!

@vehbirestelica
Copy link

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

@jzskca
Copy link

jzskca commented Mar 27, 2021

@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;

@wojtekmaj
Copy link
Owner

wojtekmaj commented Apr 1, 2021

@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!

@ghost
Copy link

ghost commented May 13, 2022

This worked for me with Webpack 5 and react-pdf 5.7.2:

// webpack.config.js
const CopyPlugin = require('copy-webpack-plugin');

export default {
  ...
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.join(
            path.dirname(require.resolve('pdfjs-dist/package.json')),
            'legacy',
            'build',
            'pdf.worker.js',
          ),
          to: resolvePath('build/public/assets'), // your public directory here
        },
      ],
    }),
  ],
}
// pdfViewer.jsx
import React from 'react';
import { Document, Page, pdfjs } from 'react-pdf';

pdfjs.GlobalWorkerOptions.workerSrc = '/assets/pdf.worker.js';

class PDFViewer extends React.Component {
  <Document ...>
    ...
  </Document>
}

@saadhashmi
Copy link

Hi, i am facing a similar issue but i dont have a file in the repo structure. Instead i am upload a file using input element file. I have the file object throught he file handler. When i feed that file by doing URL.createObjectURL(fileObject) ... i am getting that error.

@lewisMachilika
Copy link

Please advise what I am missing here it is not working at all. The error is Failed to load PDF file.

import { useState } from 'react';
// import { Document, Page } from 'react-pdf/dist/esm/entry.webpack';
import { Document, Page, pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
const ReactPdf = ({url}) => {
	const [numPages, setNumPages] = useState(null);
	const [pageNumber, setPageNumber] = useState(1);

	const onDocumentLoadSuccess = ({ numPages }) => {
		setNumPages(numPages);
	};

	const goToPrevPage = () =>
		setPageNumber(pageNumber - 1 <= 1 ? 1 : pageNumber - 1);

	const goToNextPage = () =>
		setPageNumber(
			pageNumber + 1 >= numPages ? numPages : pageNumber + 1,
		);

	return (
		<div>
			<nav>
				<button onClick={goToPrevPage}>Prev</button>
				<button onClick={goToNextPage}>Next</button>
				<p>
					Page {pageNumber} of {numPages}
				</p>
			</nav>

			<Document
				file="../assets/pdf/statement.pdf"
				onLoadSuccess={onDocumentLoadSuccess}
			>
				<Page pageNumber={pageNumber} />
			</Document>
		</div>
	);
};

export default ReactPdf;

@johnbabu021
Copy link

yes it worked for me

@kishore-s-15
Copy link

@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.

@codiejay
Copy link

codiejay commented Oct 30, 2022

@saadhashmi please what do i do i if I wanted to load the PDF that doesnt exist on my file structure but a file on the internet like this one: https://www.africau.edu/images/default/sample.pdf

This is what my code currently looks like:

<Document onLoadError={console.error} file="https://www.africau.edu/images/default/sample.pdf" onLoadSuccess={() => {console.log("ok")}}>

@yagnesh16697
Copy link

image

Working fine as separate app but getting this error while importing this app as npm package inside different app.

@zeus-singlifeph
Copy link

Hi @wojtekmaj i have a protected pdf file but the password has a Ñ and it stuck on the loading and for my another file with no Ñ it's working do you have an idea on this issue? T.I.A

@keremcanb
Copy link

keremcanb commented Sep 25, 2023

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).

I followed this example. I only replaced "copy-pdfjs-worker" with "prebuild" and it worked.

"prebuild" : "cp ./node_modules/pdfjs-dist/build/pdf.worker.js public/scripts"

Then used it like this:

    useEffect(() => {
        pdfjs.GlobalWorkerOptions.workerSrc = `${process.env.PUBLIC_URL}/scripts/pdf.worker.js`;
    }, []);

EDIT: I disabled the prebuild script above and manually copied pdf.worker.js to the public directory, and it still works. I'm a bit confused, why it is suggested that we need to copy it to public directory only during the build process? As copying it manually before also seems to work. What am I missing here? Thanks.

@wojtekmaj
Copy link
Owner

You're not missing anything. Doing this before/after/during build is the safest best. What else could you hook it to?

@wandersonce
Copy link

@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)

worked perfectly! thanks

@preveenraj
Copy link

For CRACO,
This worked for me.

I used the version:
"react-pdf": "5.0.0"

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

pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  'pdfjs-dist/build/pdf.worker.min.js',
  window.location.href,
).toString();

@feri-irawan
Copy link

@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 just tried this but error 404, i solved this error using jsdlivr

pdfjs.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`

@wojtekmaj
Copy link
Owner

I just tried this but error 404

That's because "pdf.worker.js" changed to "pdf.worker.min.mjs" in the recent React-PDF update.

@marcioj-io
Copy link

Hi, you can do it this way:

The issue occurs because, in React, files in the public folder should be referenced directly as relative URLs, without using import. Instead of:

import cvPDF from '../../../public/assets/cv.pdf';

You can simply use a relative URL in the downloadPDF function:

const downloadPDF = () => {
  const link = document.createElement('a');
  link.href = '/assets/cv.pdf'; // Relative path to the public folder
  link.download = 'CV-MJ-Full-Stack.pdf';
  link.click();
};

This way, React won't attempt to resolve the path dynamically, and it will directly fetch the file from the public folder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests