» npm install @cyntler/react-doc-viewer
Want to create a custom document viewer.
reactjs - react-doc-viewer won't show Docx file, shows blank - Stack Overflow
reactjs - @cyntler/react-doc-viewer get LocalFiles in React - Stack Overflow
Re-render causes document in react-doc-viewer to be hidden
Videos
I am asked to create a custom document viewer . ( doc types include - csv's , pdf's , xlsx , ppt's etc. etc.. all the common document types )
I used these 2 libraries :
react-doc-viewer
cyntler/react-doc-viewer
Both support multiple file types , but the '.doc' and '.docx' types are supported only with public URL's
( a few more file types are also supported only with public URL's ).
In my use case I will be using S3 Links to fetch the document and render them.
Since s3 links are private ( and we don't intend to change this ). What can I use to render the doc and docX type?
Is there any other alternative to those libraries ( free ) that I can use where It renders multiple file types?
Reference of roughly what I need to create.
The docx file MUST be a publicly accessible url.
Local files will NOT work because the docx renderer (which uses an external service) needs to be able to access the url.
import DocViewer, { DocViewerRenderers } from "@cyntler/react-doc-viewer";
function App() {
return (
<div style={{ height: "100vh", width: "100vw" }}>
<DocViewer
documents={[{ uri: "http://your-publicly-accessible-url.docx", fileType: "docx" }]}
pluginRenderers={DocViewerRenderers}
/>
</div>
);
}
I found this GitHub issue very helpful Docx not working GitHub Issue
Adding a File type worked for me, { uri: require("./Dynamic_tabs.docx"), fileType: 'docx' },
» npm install @vvelediaz/react-doc-viewer
Created a simple app with cyntler/react-doc-viewer v:1.16.6
to view pdf documents in browser. Works fine initially but on re-render hides the document, note: the viewer will still be present but the document is not visible.
The code :
App.jsx
import { useState } from 'react'
import DocViewer,{DocViewerRenderers} from "@cyntler/react-doc-viewer";
import 'react-pdf/dist/Page/AnnotationLayer.css';
import 'react-pdf/dist/Page/TextLayer.css';
import './App.css'
function App() {
const [count, setCount] = useState(0)
return (
<>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
</div>
<div>
<DocViewer style={{minHeight:'400px',minWidth:'500px'}} pluginRenderers={DocViewerRenderers} config={{header:{disableHeader:true}}} documents={[{uri:'/sample-1.pdf'}]}/>
</div>
</>
)
}
export default App
What could be causing this issue??
I have checked the network tab and it shows that it request the doc Url on every re-render.
Isn't DocViewer a memoized component its props are not changing so shouldn't it keep the same Url as the source??
EDIT: There seems to be a issue created in the repo for this exact issue (Issue #283).
Even there the fix suggested (also suggested by u/eindbaas) is to add key prop to the DocViewer that gets updated with every prop change.
I have limited the re-render of the on only url prop changes so this fix works for me.
You can add a custom loader in the package documentation
const MyLoadingRenderer = ({ document, fileName }) => {
const fileText = fileName || document?.fileType || "";
if (fileText) {
return <div>Loading Renderer ({fileText})...</div>;
}
return <div>Loading Renderer...</div>;
};
<DocViewer
pluginRenderers={DocViewerRenderers}
documents={
{
// ...
}
}
config={{
loadingRenderer: {
overrideComponent: MyLoadingRenderer,
},
}}
/>;
I passed all the docs
<Grid item xs={12} md={8} style={{ height: "100%" }}>
<DocPreview doc={selectedDoc} docs={docs.data?.map((doc) => { return { fileType: doc?.fileType, fileName: doc?.name, uri: doc?.uri } })} />
</Grid>
and in the doc preview used activeDocument prop
export default function DocPreview({ doc, docs = [] }) {
return (
<DocViewer prefetchMethod="GET" style={{ borderRadius: "10px", height: "100%" }}
documents={docs}
activeDocument={{ fileType: doc?.fileType, fileName: doc?.name, uri: doc?.uri }}
pluginRenderers={DocViewerRenderers}
/>
)
}