Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Full-fledged PDF.js viewer in React

I'm looking to use the full-featured PDF.js in a React component in a Next.js project, as seen in Firefox and as on this online demo. Some important features here are being able to navigate to a certain page number by typing it in, and searching for text in the PDF. Is there a React component available for that?

The library react-pdf is nice for rendering a single page, but doesn't provide a toolbar or a convenient way of lazily loading pages in a scrollable view.

Similar to the questions How to use full PDF.js viewer with toolbar in webpack and Vuejs? (where the accepted answer provides a Vue component) and Embed Full Mozilla pdf.js viewer in vue.js ( using webpack via vue-cli ), but for React.js.

I tried including including /web/viewer.html as part of the inner HTML of a React component by doing the following, but it didn't work out.

  1. Download the latest release and extract it to a folder part of my Next.js project (which I called pdfjs). I tried several folders, such as /client, /client/components, /pages, /node_modules, and /.
  2. Run npm install --save-dev html-loader
  3. Use this Webpack loader that parses HTML files, by changing next.config.js to the following:
module.exports = {
  // …
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.html$/,
      exclude: /node_modules/,
      use: { loader: 'html-loader' }
    });
    return config;
  },
}
  1. Create a simple page under /pages as follows:
import React from 'react';
import PdfViewer from '../pdfjs/web/viewer.html'

export default function () {
  return (
    <div className="content" dangerouslySetInnerHTML={{ __html: PdfViewer }} />
  );
};
  1. After running next in terminal to start a dev server and navigating to that page in the browser, I get an error about the JavaScript heap running out of memory.

Even if my computer had enough memory, I'm not sure that this would actually result in the PDF rendering – not to mention the danger of using dangerouslySetInnerHTML. It looks like a better solution would probably be to have an actual React component rather than trying to embed an HTML file.

like image 423
mic Avatar asked Apr 08 '20 01:04

mic


1 Answers

I think this might be more of what your after. I wrapped it in a component for you already but this is a document viewer which can view PDF documents with out much work.

import  React,{  Component } from 'react';
import ReactDOM from 'react-dom';


class DocView extends React.Component{

    constructor(props){
        super(props);
    }

    render(){
        var url = "https://docs.google.com/viewerng/viewer?url="+this.props.src+"&embedded=true";
        return(
            <iframe style={this.props.style} src={url}></iframe>
        );
    }
}

export default DocView;

enter image description here

like image 91
jgetner Avatar answered Nov 11 '22 22:11

jgetner