Is there a way to set 100% width to the pdf so that it occupies the full width of the container?
I can see width property takes input only in pixels but not in percentage.
The solution in the fork seems okay. Just mind it just scales PDF once, not sure if that's desired.
It would be entirely possible in this repo., only I'd do this outside <Document>. What I would do is I'd create a wrapper component, set its width to desired using CSS, measure it using JavaScript and provide the result to the child Document component. Then, make sure to watch for window resize to update the measurements (don't forget to throttle!).
I currently have no plans of implementing width prop other than value in pixels. Other values would be quite problematic and supporting all possible cases would probably result in untestable mess.
Hey @wojtekmaj I'm interested in this aswell since I'll need to implement it soon. Your suggestion seems more appropriate. Do you mean something like this?
import React, { PureComponent } from "react"
import { Document, Page } from "react-pdf/build/entry.webpack"
import throttle from "lodash.throttle"
import pdf from "./pdf.pdf"
class App extends PureComponent {
constructor(props) {
super(props)
this.state = {width: null}
}
componentDidMount () {
this.setDivSize()
window.addEventListener("resize", throttle(this.setDivSize, 500))
}
componentWillUnmount () {
window.removeEventListener("resize", throttle(this.setDivSize, 500))
}
setDivSize = () => {
this.setState({width: this.pdfWrapper.getBoundingClientRect().width})
}
render() {
return (
<div id="row" style={{height: "100vh", width: "100vw", display: "flex", overflow: "hidden"}}>
<div id="placeholderWrapper" style={{width: "10vw", height: "100vh"}}/>
<div id="pdfWrapper" style={{width: "90vw"}} ref={(ref) => this.pdfWrapper = ref}>
<PdfComponent wrapperDivSize={this.state.width} />
</div>
</div>
)
}
}
class PdfComponent extends PureComponent {
render() {
return (
<div>
<Document
file={pdf}
>
<Page pageIndex={1} width={this.props.wrapperDivSize} />
</Document>
</div>
)
}
}
export default App
Precisely what I meant @lucasveigaf! Good job :)
One thing - on componentWillUnmount you wanted to call removeEventListener, I suppose. Other than that, cool!
Thanks, @wojtekmaj, Oh yes, ofc, I'll update it. Great job on the component, btw.
For the intrepid developer stumbling across this issue, there is a bug in the provided solution:
componentDidMount () {
this.setDivSize()
window.addEventListener("resize", throttle(this.setDivSize, 500))
}
componentWillUnmount () {
window.removeEventListener("resize", throttle(this.setDivSize, 500))
}
The use of Lodash's throttle here is a problem as it returns a new function. Since removeEventListener removes the given function based on reference, you'll never actually remove your listener here as you're always adding a new, untracked function reference.
See the attached screenshots for examples.
As a solution, one could assign a method with the results from _.throttle, e.g.
handleResize = _.throttle(() => {
// Code goes here
}, someTimeValue);


in gist file he has updated this. https://raw.githubusercontent.com/lucasveigaf/react-pdf-example/master/src/App.js
Evening all
I agree with @wojtekmaj comments and place this outside the Document:
It would be entirely possible in this repo., only I'd do this outside
The approach I have taken to solve this problem, is to leverage the library react-sizeme
And creating a wrapper around the document as follows:
<SizeMe
monitorHeight
refreshRate={128}
refreshMode={"debounce"}
render={({ size }) => (
<div>
<Document
file={pdf_data_uri}
onLoadSuccess={this.onDocumentLoadSuccess}
onLoadError={this.onDocumentLoadError}
>
<div className={classes.pageBorder}>
<Page width={size.width} pageNumber={pageNumber} />
</div>
</Document>
</div>
)}
/>
This will allow for the resizing both vertically and horizontally.
Thanks
Keaton
I've just seen this. Wonder why not do it with CSS? Like this:
const PDFDocumentWrapper = styled.div`
canvas {
width: 100% !important;
height: auto !important;
}
`;
<PDFDocumentWrapper>
<Document
file={`/etc...`}
>
<Page pageNumber={1} />
If not using styled-components, then you could obviously target the element using a className instead.
import AutoSizer from 'react-virtualized/AutoSizer';
_renderPdf = () => {
const {
blob,
pdfNumPages,
} = this.props.cstore;
return (
<AutoSizer disableHeight>
{({width}) => (
<Document file={blob} onLoadSuccess={this._handlePdfLoaded}>
{[...Array(pdfNumPages).keys()].map((i) => (
<Page key={i} pageNumber={i + 1} width={width} />
))}
</Document>
)}
</AutoSizer>
);
}
I've just seen this. Wonder why not do it with CSS? Like this:
const PDFDocumentWrapper = styled.div` canvas { width: 100% !important; height: auto !important; } `;<PDFDocumentWrapper> <Document file={`/etc...`} > <Page pageNumber={1} />If not using styled-components, then you could obviously target the element using a className instead.
This option works in a purely css option. But it does not scale the pdf losing text quality and more.
Came up with the following solution
import React, { Component } from 'react';
import throttle from 'lodash.throttle';
class MakePDFResponsive extends Component {
constructor(props) {
super(props)
this.state = {
PDFWidth: null
}
this.myInput = React.createRef()
}
componentDidMount() {
// setting width at initial
this.setPDFWidth()
// event listener when window is resized
window.addEventListener('resize', throttle(this.setPDFWidth, 500))
}
componentWillUnmount() {
window.removeEventListener('resize', throttle(this.setPDFWidth, 500))
}
setPDFWidth = () => {
const width = this.myInput.current.offsetWidth
this.setState({ PDFWidth: width })
}
render() {
const { PDFWidth } = this.state
return (
<div ref={this.myInput}>
<Document file='test.pdf'>
<Page pageNumber={1} width={PDFWidth} />
</Document>
</div>
)
}
}
@Haseeb99 your removeEventListener won't work because
throttle(this.setPDFWidth, 500) === throttle(this.setPDFWidth, 500) // false
I suggest the following modfication:
+ throttledSetPDFWidth = throttle(this.setPDFWidth, 500);
componentDidMount() {
// setting width at initial
this.setPDFWidth()
// event listener when window is resized
- window.addEventListener('resize', throttle(this.setPDFWidth, 500))
+ window.addEventListener('resize', this.throttledSetPDFWidth);
}
componentWillUnmount() {
- window.removeEventListener('resize', throttle(this.setPDFWidth, 500))
+ window.removeEventListener('resize', this.throttledSetPDFWidth)
}
Got it Thank you
@lucasveigaf @Haseeb99 hey guys do your solutions keep the pdf quality intact on different devices ?
I was just trying this solution by inspecting it for different devices in chrome ...pdf scaled flawlessly but I saw quality degraded as if nothing was visible on smaller width devices ... while I have not tried it on actual devices as I will have to make build for them and stuff so was just asking if it works just fine ?
answer would be appreciated
Thanks !
P.S. attached is the screenshot for mobile screen

To force the height to 100% add
.react-pdf__Page__canvas {
min-height: 100vh ! important;
max-width: 100vw! important;
}
renderMode is the same as canvas, if you have svg look at the wrapper class.
@igorskiter Merged your comments into one.
Your solutions scales PDF so that it fits the page, but doesn't take into account that it may be blurred, because it wasn't rendered in desired size. Unfortunately React-PDF _must_ know the size of the page to render. It can derive it from the PDF itself, but if you want the page to scale to fit the screen, this is unlikely what you want.
An improvement to @keatonvictor 's solution, using react-sizeme:
<SizeMe>
{({ size }) => (
<Document file={filename}>
<Page pageNumber={1} width={size.width ? size.width : 1} />
</Document>
)}
</SizeMe>
width = {document.getElementById('root').clientWidth}
onLoadSuccess={this.onDocumentLoadSuccess}
onLoadError={console.error}
>
{Array.from(
new Array(numPages),
(el, index) => (
key={page_${index + 1}}
pageNumber={index + 1}
/>
),
)}
Most helpful comment
Hey @wojtekmaj I'm interested in this aswell since I'll need to implement it soon. Your suggestion seems more appropriate. Do you mean something like this?