react-pdf: Using custom font causes usePDF instance to indefinitely remain as 'loading'
Describe the bug Registering a custom font with Font.register() results in usePDF never generating the PDF as expected. Commenting out the use of the custom font in StyleSheet allows PDF to generate, which leads me to believe it is an issue with how @react-pdf/renderer instantiates custom fonts. There is no error thrown, making it very difficult to diagnose the issue…
To Reproduce This minimal example of index.tsx shows the reproducible error (React 18, Webpack 5 configuration, NOT Create React App):
import React from 'react'
import ReactDOM from 'react-dom/client'
import { Document, Page, Text, Font, usePDF, StyleSheet } from '@react-pdf/renderer'
import ArialBold from './arial-bold.ttf'
Font.register({
family: 'Arial',
fonts: [
{
src: ArialBold,
fontStyle: 'normal',
fontWeight: 'bold'
}
]
})
const styles = StyleSheet.create({
heading: {
//comment these 2 lines out and it will generate PDF properly
fontFamily: 'Arial',
fontWeight: 'bold',
fontSize: 20,
color: '#006699'
}
})
const App = () => {
const [instance] = usePDF({
document: (
<Document title={'Title'} author={'Author'} subject={'Subject'} pageMode="useNone">
<Page size="A4">
<Text style={styles.heading}>text1</Text>
<Text>text2</Text>
<Text>text3</Text>
</Page>
</Document>
)
})
console.log('ArialBold', ArialBold)
console.log('Font.getRegisteredFonts().', Font.getRegisteredFonts())
console.log('instance', instance)
return (
<a href={instance.url || undefined} download={'filename.pdf'}>
DOWNLOAD PDF
</a>
)
}
const root = ReactDOM.createRoot(document.getElementById('root')!)
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
)
Output of console.logs shows the path to the font and the font being registered, however the instance.loading remains = true indefinately. I have followed the path to the font and the path is correct
14:25:01.850 index.tsx:39 ArialBold /media/arial-bold.ff5427169c7aaacb3946.ttf 14:25:01.850 index.tsx:40 Font.getRegisteredFonts(). {Arial: Font} 14:25:01.850 index.tsx:41 instance {url: null, blob: null, error: null, loading: true}
Expected behavior PDF is available to download via instance.url
Desktop (please complete the following information):
- OS: Windows 10
- Browser: Chromium
- React-pdf version: 3.3.8
About this issue
- Original URL
- State: open
- Created 4 months ago
- Reactions: 29
- Comments: 31
Commits related to this issue
- Add support for BC Sans font in PDFs [BPHH-1074] https://github.com/diegomura/react-pdf/issues/2675#issuecomment-1999002409 — committed to bcgov/HOUS-permit-portal by LaurelOlson 3 months ago
- Add support for BC Sans font in PDFs [BPHH-1074] https://github.com/diegomura/react-pdf/issues/2675#issuecomment-1999002409 — committed to bcgov/HOUS-permit-portal by LaurelOlson 3 months ago
- Add support for BC Sans font in PDFs [BPHH-1074] https://github.com/diegomura/react-pdf/issues/2675#issuecomment-1999002409 — committed to bcgov/HOUS-permit-portal by LaurelOlson 3 months ago
- Add support for BC Sans font in PDFs [BPHH-1074] https://github.com/diegomura/react-pdf/issues/2675#issuecomment-1999002409 — committed to bcgov/HOUS-permit-portal by LaurelOlson 3 months ago
@cduff Appreciate you posting this. Thank you, this fixed worked. By adding this to the Resolutions/Overrides. These issues have been fixed.
NPM package.json
"overrides": { "restructure": "3.0.0" }or Yarn/PNPM package.json"resolutions": { "restructure": "3.0.0" }What was your process to be able to find this? Curious for future issues. Did you look into the lock file, look into fontkit and dependencies and go one by one to see recent upgrades?
I was hit by this too. After some investigation, it seems to have been caused by the underlying restructure dependency updating from 3.0.0 to 3.0.1.
@PelosiTech I noticed it broke from one deployment to the next even though the version of
@react-pdf/rendererremained the same. From the git commit log I could seenpm updatehad been run. I did a diff onpackage-lock.jsonand compared to the list of dependencies of@react-pdf/rendererretrieved usingnpm list --all. There was a single package that featured in both lists - therestructurepackage, updated from 3.0.0 to 3.0.1.It seems I’m encountering the same issue.
I have the same problem also.
Yes, worked for me.
Same problem!
I’m also running into this issue. I am producing a PDF via the
renderToStream()function. After that I collect the stream into a byte array, so I can store the bytes into a cloud storage.When running this code, with a custom font, I see that chunks of stream content are getting loaded, but the “end” stream event is never called. It simply hangs on the last chunk and the promise is never resolved
@Frontend-io I have a merged PR in the dep’s dep that fixes it. Just waiting for @devongovett to make a new restructure release to patch.
I have the same issue. When downloading an example google font from this list and importing that, it does work (for example with http://fonts.gstatic.com/s/roboto/v16/zN7GBFwfMP4uA6AR0HCoLQ.ttf)
However when I then open the same file in FontForge, and export it as “bad.ttf” without changing any of the settings, it suddenly Fails:
It also seems to fail on any other non google font in my experience. Can it be that it somewhere only accepts fonts that match the checksum of fonts available via google fonts? Is there any other unspecified encoding parameter that determines if it can handle the .ttf file? There really seems to be barely a difference in the files… I am lost
font files for reference
I have a smaller repro see https://github.com/foliojs/fontkit/issues/331#issuecomment-2040790107
And (edit) have a fix PR in https://github.com/foliojs/restructure/pull/62
edit the restructure PR was merged…
I do have the same issue. However, I noticed it’s not the
Font.registerwhich does break my code, but the usage of the font which is registered within the styles. Not sure if it does make a difference but might be a small hint for debugging the issue.also it seems the intermediate dependency is
@react-pdf/render->@react-pdf/font->fontkit->restructureHi @diegomura, any updates on this issue? can we add a lock file to ensure this doesn’t happen again?
I’m guessing a bug was introduced into restructure in 3.0.1. Just now I can’t see any new issues listed in its repo related to this: https://github.com/foliojs/restructure/issues.
I’m not familiar enough with the internal workings of
react-pdfand its use ofrestructureto be able to efficiently do this. I wonder if we can get help from a maintainer for this?@diegomura FYI @devongovett
Thanks man, you made my day! Been debugging this issue for the past two nights!
Hi. I’m new to these tools, but I’m trying to create a repro so I can investigate what’s happening in restructure. Can anyone give some pointers on how to get from a simple repro?
What I’m trying currently:
webpackbranch)arialbd.ttffrom my duly licensed win11npm iandnpm startTwo days fighting this very issue! Indeed, overriding “restrucuture” module to use v. 3.0.0 solves it. Thank yall, so much!
Yes, that’s correct. In my example I originally posted, commenting out the use of the custom font in the stylesheet fixes the issue.
At the moment, overriding the restructure package back to 3.0.0 is the correct workaround, as others have noted above.
Great, I spend hours yesterday to find the broken dependency without success. Thank you!
Not really an option for a lot of users that have to adhere to style guides… 😦
The way we resolved this was by going back to using the system packaged fonts. We had to fully abandon the use of imported fonts for now.
face same problem with next.js when using
const blob = await pdf(MyDoc).toBlob()I am using diffrent fonts, but facing issue in only one font (Greycliff CF) , other all fonts are working. also another point is issue arise only on my server, in localhost its working with “Greycliff CF” font