Closed stevensacks closed 2 years ago
Hello,@diegomura
i had this issue yesterday when i was refactoring a previously working code. My issue was definitely like the one reported here https://github.com/diegomura/react-pdf/issues/636 . On chrome debugging tool the variable sent to the function buildSubsetForFont was null. I could not reproduce this issue on codesandbox.
. While searching in the react-pdf code I have noticed that the Font class has a name issue on its register method. this.fontFamily should be "this.family". I am not sure if this is the reason for this error. I could not look deeper and now my code is working again and the Font is included on my PDF file. I will look again later on this.
class Font { static create(family) { return new Font(family); }
constructor(family) { this.family = family; this.sources = []; }
register({ src, fontWeight, fontStyle, ...options }) { this.sources.push( new FontSource(src, this.fontFamily, fontStyle, fontWeight, options), ); }
hi I'm getting the same problem, what should I do? I will appreciate any help thanks. styles.js import {Font, StyleSheet} from "@react-pdf/renderer"; import regular from "./Roboto-Regular.ttf"; import boldd from "./Roboto-Bold.ttf"; Font.register({ family: 'Roboto', fonts: [ { src: regular }, { src: boldd, fontWeight: 'bold' } ] })
I was having the same issue, so I took the tip from @SamJarmanPP
- 1, this is happening intermittently for me too. I register custom fonts as early as I can in the application lifecycle.
and basically what I did was create a function in my index.js file and call it in a useEffect hook only after the initial render as follows
`const registerFont = () => { Font.register({ family: "Montserrat", src: "http://fonts.gstatic.com/s/montserrat/v10/zhcz-_WihjSQC0oHJ9TCYC3USBnSvpkopQaUR-2r7iU.ttf", }); };
useEffect(() => { registerFont(); }, []);`
That seems to have worked and I'm not seeing the error anymore.
Anyone stumbling on this who is using PDFDownloadLink, I ended up using this solution to generate the PDFs on user click and it ended up working!
For help How to solve this error?
This happens using the v2 branch as well (@2.0.0-beta.14
).
I had this problem using NextJS. I solved this problem using require and installing next-fonts
. So a downloaded the .tff and put it at the same folder. This was a really tricky problem, I tried using static folder and url. It was working at dev mode and local builds, but once I sent to production using AWS Amplify, my PDF Viewer was broken.
const font = require('./mplus.ttf')
Font.register({
family: 'mplus-1',
src: font
})
I have tried all the above things and still I am getting the same error. Please help.
I am getting this error:- Unhandled Rejection (TypeError): Cannot read property 'hasGlyphForCodePoint' of null
Same issue.
The error occurs not by registering the fonts but by using the registered fonts inside the stylesheet as a fontFamily.
const PDFstyles = StyleSheet.create({
text: {
fontFamily: 'Open Sans'
}
})
Font.register({
family: 'Open Sans',
src: 'http://fonts.gstatic.com/s/opensans/v18/mem8YaGs126MiZpBA-UFVZ0ef8pkAg.ttf'
})
When the fontFamily is commented the error disappears.
const PDFstyles = StyleSheet.create({
text: {
// fontFamily: 'Open Sans'
}
})
Font.register({
family: 'Open Sans',
src: 'http://fonts.gstatic.com/s/opensans/v18/mem8YaGs126MiZpBA-UFVZ0ef8pkAg.ttf'
})
But of course in this case it's useless to Register the fonts because it's not possible to use them.
Getting this same error with the following code on v1.6.11:
<Modal open={open} onClose={close}>
<Modal.Content >
<StyledPDFViewer>
<PDFViewer>
<Invoice data={invoiceData} />
</PDFViewer>
</StyledPDFViewer>
<Button>
<PDFDownloadLink document={<Invoice data={invoiceData} />}>
{({ blob, url, loading, error }) => {
if (loading) return <Loader />;
return 'Download Invoice';
}}
</PDFDownloadLink>
</Button>
</Modal.Content>
</Modal>
The error only occurs when I'm rendering the component in two different places, like you can see above.
In my example, <Invoice />
is a <Document />
component.
I'm using <PDFViewer>
to display the generated PDF to the user. Then I'm using <PDFDownloadLink />
to give the user the option of downloading the PDF. When I remove the <PDFDownloadLink />
OR replace the document property with a different <Document />
component the error goes away.
Closing the modal (which I'm getting from 'semantic-ui-react'), and then opening it again seems to resolve the issue every time, replacing the loading state with the proper 'Download Invoice' text, at which point they can download the PDF successfully.
Any ideas how to fix this in the context of my example?
Thanks!
Thank you for @eldieco
I'm using it as below.
function App() {
const [isOnPdfView, setIsOnPdfView] = React.useState(false)
React.useEffect(() => {
setTimeout(() => {
setIsOnPdfView(true)
}, 1000);
}, [])
return (
<div className="App">
<PDFViewer style={{height: 1000, width: 500}}>
<MyDocument />
</PDFViewer>
{isOnPdfView && <PDFDownloadLink document={<MyDocument />} fileName="invoice.pdf">
{({ blob, url, loading, error }) => (loading ? 'Loading document...' : 'Download now!')}
</PDFDownloadLink> }
</div>
);
}
I was having the same issue, so I took the tip from @SamJarmanPP
- 1, this is happening intermittently for me too. I register custom fonts as early as I can in the application lifecycle.
and basically what I did was create a function in my index.js file and call it in a useEffect hook only after the initial render as follows
`const registerFont = () => { Font.register({ family: "Montserrat", src: "http://fonts.gstatic.com/s/montserrat/v10/zhcz-_WihjSQC0oHJ9TCYC3USBnSvpkopQaUR-2r7iU.ttf", }); };
useEffect(() => { registerFont(); }, []);`
That seems to have worked and I'm not seeing the error anymore.
@amamenko It Worked for me too. Thanks.
Hello, guys, I had similar issue. In my case, this type of code was causing the error:
<View render={() => { return <Text style={styleWithImportedFonts}></Text>/>
So the fix was simple:
<View style={styleWithImportedFonts} render={() => { return <Text style={styleWithImportedFonts}></Text>/>
hope it helps!
Hello guys, Having the same issue, I tried the workaround from @SamJarmanPP but no luck still getting
Cannot read property 'hasGlyphForCodePoint' of null
is there another way to overcome this issue?
Hello folks, I am having the same issue working with<PDFDownloadLink/>
and Font.register
if I remove the registered font from the style it works quite similar to what @cloetensbrecht posted
Changing the buildSubsetForFont
function from
const buildSubsetForFont = font =>
IGNORABLE_CODEPOINTS.reduce((acc, codePoint) => {
if (font.hasGlyphForCodePoint && font.hasGlyphForCodePoint(codePoint)) {
return acc;
}
return [...acc, String.fromCharCode(codePoint)];
}, []);
to
const buildSubsetForFont = font =>
IGNORABLE_CODEPOINTS.reduce((acc, codePoint) => {
if (font) {
if (font.hasGlyphForCodePoint && font.hasGlyphForCodePoint(codePoint)) {
return acc;
}
return [...acc, String.fromCharCode(codePoint)];
}
return [...acc, String.fromCharCode(codePoint)];
}, []);
would, at the very least, prevent the entire app from crashing since you can't run the fontkit method hasGlyphForCodePoint
on a null
value.
thanks, @amamenko for the answer, it didn't work for me, it breaks in other places now
@amamenko, Thanks for the response. It worked for me..
And I'm using patch-package to add this patch..
Looks like I was not registering fonts correctly and latest react-pdf 2.0 throws exception.. Once I'm registering fonts correctly this exception is not thrown...
Can someone share a way I can replicate this? It's hard to see why based on the discussion above
Can someone share a way I can replicate this? It's hard to see why based on the discussion above
Yes indeed, we found out how to simulate this on codesandbox.io:
https://codesandbox.io/s/dazzling-night-0io97?file=/src/App.js
You have to open the link via google chrome (https://0io97.csb.app/) and set network throttling (slow 3g) in your browser. Then click 'get multiple blob' 😄
This problem appears only when you need to display/open multiple pdfs and the first one is using other custom fonts than any of the later ones. It appears that it's some kind of promise which only registers fonts necessary to render the first pdf. It's get resolved when the first pdf is rendered and other pdfs are also rendered despite the fact that their fonts are not registered.
It is easier to simulate when you have network throttled or big pdfs, but from time to time it also happens on a fast connection.
Any updates on this? Having the same issues. No solutions above working. I like @amamenko but would be nice if it's implemented upstream. Thanks all ; )
Any word on this? Would it be possible to merge my PR so it doesn't crash the application and uses the fallback font if no font is found?
Merged already. Closing this
problem still happens. any solution? this only happens when trying to render PDFDownloadLink multiple times in one page.
Same issue.
The error occurs not by registering the fonts but by using the registered fonts inside the stylesheet as a fontFamily.
const PDFstyles = StyleSheet.create({ text: { fontFamily: 'Open Sans' } }) Font.register({ family: 'Open Sans', src: 'http://fonts.gstatic.com/s/opensans/v18/mem8YaGs126MiZpBA-UFVZ0ef8pkAg.ttf' })
When the fontFamily is commented the error disappears.
const PDFstyles = StyleSheet.create({ text: { // fontFamily: 'Open Sans' } }) Font.register({ family: 'Open Sans', src: 'http://fonts.gstatic.com/s/opensans/v18/mem8YaGs126MiZpBA-UFVZ0ef8pkAg.ttf' })
But of course in this case it's useless to Register the fonts because it's not possible to use them.
I can replicate this on my end intermittently and this was also my issue.
fontFamily
inside the StyleSheet.create()
produced the discussed error.
Do someone knows what are other ways to modify the font family?
I'm using "@react-pdf/renderer": "1.6.13"
.
Thanks.
I've got a task to generate dozens of PDF-links on a single page. After days and days of digging around this issue, I've found that:
1) The problem is caused by using fonts in PDF docs. 2) And it happens only if several PDF docs or links are being generated on a single page simultaneously (while using fonts)
So, the only workaround I've found is to line up all PDF docs (or PDF links) in a single queue and generate them one by one sequentially. It's easy to do by using a hook "useQueuedEffect" like so:
import { useState, useCallback } from 'react'; import { useQueuedEffect } from 'react-queued-effect'; import { pdf } from '@react-pdf/renderer';
function PDFLink({ filename, document }) {
const [ url, setUrl ] = useState();
const [ err, setErr ] = useState();
const renderPdf = useCallback(() =>
pdf(document).toBlob()
.then(blob => setUrl(URL.createObjectURL(blob)))
.catch(err => setErr(err || 'Unknown error'))
, [document]);
useQueuedEffect(renderPdf);
if (url) {
return <a download={ filename || 'download.pdf' } href={url}>Download PDF</a>
};
if (err) {
console.error('PDFLink: failure to render a document', err)
return <p>{ err }</p>
};
return <p>Loading...</p>;
}
Hi Reymark,
I've just published a TypeScript-native version of the useQueuedEffect hook. Check version 2.0.0 at npmjs.org With the typescript-native version you shouldn't have any issues regarding TS types.
BR, Fedor | +7 905 794 8477 | @.***
On Fri, Oct 15, 2021 at 5:00 AM Reymark @.***> wrote:
Hi @fedor-pavlov https://github.com/fedor-pavlov ,
Thanks your reply and your library. Looks promising. But may I know how can I implement the useQueuedEffect on TypeScript?
I'm currently having an error after installing and importing it: Could not find a declaration file for module 'react-queued-effect'. 'react-queued-effect/index.js' implicitly has an 'any' type..
Thanks.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/diegomura/react-pdf/issues/777#issuecomment-943921649, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADDYEQJNRWBIRRJTA6OCRK3UG6DLZANCNFSM4JVVXTUQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
If you're not using the PDFViewer this error doesn't seem to occur. Downloading the PDF with a registered & used font works otherwise.
use your local fontStyles. it will work!
import OpenSansBold from '@assets/fonts/feather/fonts/OpenSansBold.ttf'
import OpenSansExtraBold from '@assets/fonts/feather/fonts/OpenSansExtraBold.ttf'
import OpenSansRegular from '@assets/fonts/feather/fonts/OpenSansRegular.ttf'
const ResultPdf = () => {
Font.register({
family: 'MainFont',
fonts: [
{
src: OpenSansRegular
},
{
src: OpenSansBold,
fontWeight: 'bold'
},
{
src: OpenSansExtraBold,
fontWeight: 'bold'
}
]
})
const styles = StyleSheet.create({
page: {
fontFamily: 'MainFont'
}
})
return (
<Document>
<Page
style={styles.page}
>
//Components here
</Page>
</Document>
)
}
Describe the bug I'm using PDFDownloadLink and rendering a perfectly valid PDF document. It went from sometimes throwing this error to always throwing this error. It used to just appear in the console, but with the latest release of react-scripts (3.3.0), now when it occurs, my entire app crashes. I tried wrapping it in an ErrorBoundary but it won't catch it.
I render the document on its own prior to passing it to the PDFDownloadLink. The rendering of the document has no problems. But, if I render PDFDownloadLink with the document, my app crashes.
I don't know what it causing this, but you need to try catch this error internally so it won't just crash the entire app. Or throw it in a way that an ErrorBoundary will catch it.
To Reproduce I've figured out how to reproduce it. If you have two PDFDownloadLink's rendering the same document, or you quickly re-render the same PDFDownloadLink, it happens every time.
Expected behavior For this error not to happen anymore, or at least not crash the app and be catchable by ErrorBoundaries.
Screenshots
Desktop (please complete the following information):