react-pdf icon indicating copy to clipboard operation
react-pdf copied to clipboard

Multiple usage of `usePdf` doesn't render fonts properly

Open mkaliszewski opened this issue 3 years ago • 2 comments

Describe the bug Registered fonts are applied only for the first document when using usePdf multiple times in a single component.

To Reproduce Steps to reproduce the behavior including code snippet (if applies):

  1. Create 2 documents
  2. Register the same fonts for each of them
import robotoMedium from './fonts/Roboto-Medium.ttf'
import robotoRegular from './fonts/Roboto-Regular.ttf'

  Font.register({
    family: 'Roboto',
    fonts: [
      {
        src: robotoRegular,
        fontWeight: 'normal'
      },
      {
        src: robotoMedium,
        fontWeight: 'medium'
      }
    ]
  })
  1. Apply fonts in styles for both documents
  2. Create a component
  3. Import both documents
  4. use usePdf twice in the created component:
const [instanceOne] = usePdf({ document: <DocumentOne />})
const [instanceTwo] = usePdf({ document: <DocumentTwo />})
  1. Add anchor tag and download both PDFs

Actual behavior

Downloading both instanceOne and instanceTwo results in displaying proper fonts only for instanceOne.

If I'd change the order and it will be:

const [instanceTwo] = usePdf({ document: <DocumentTwo />})
const [instanceOne] = usePdf({ document: <DocumentOne />})

Then the instanceTwo is rendered properly and instanceOne is not.

Expected behavior Fonts should be rendered properly for both documents

Desktop (please complete the following information):

  • OS: Ubuntu
  • Browser: Chrome
  • React-pdf version v2.1.1

mkaliszewski avatar Mar 26 '22 23:03 mkaliszewski

I'm seeing the same behavior. Can mix and match <PDFDownloadLink> and <PDFViewer> as well, it's always the same story: fonts are properly displayed in whichever instance comes first, and later instances do not have custom fonts.

  • OS: Windows 10
  • Browser: Firefox
  • React-pdf v2.1.1

isaaclyman avatar Mar 30 '22 02:03 isaaclyman

One temporary solution could be use await pdf(<Document {...props} />, get Blob or whatever the data type you want, and then trigger asynchronous download, code snippet like this:

const blob = await pdf(<Document {...props} />).toBlob();
const url = window.URL.createObjectURL(blob);
let tempLink = document.createElement('a');
tempLink.href = url;
tempLink.setAttribute('download', `file-name.csv`);
tempLink.click();

hebuliang avatar May 11 '22 12:05 hebuliang