react-pdf: Loading and registering fonts is broken

Describe the bug When attempting to load the source of a font, locally or from an external URL, an error comes back as Error: Unknown font format like in your example here

https://react-pdf.org/repl?example=font-register

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

  1. Register a font
  2. See console errors & failure to load the doc

Expected behavior Fonts are loaded successfully and applied to the document.

Screenshots

Screenshot 2019-08-05 at 15 37 23

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 8
  • Comments: 36 (2 by maintainers)

Most upvoted comments

I had this issue as well. I was able to resolve it by importing the font file as a variable then using that as the src value.

import font from "./font.ttf"

Font.register({
  family: "FamilyName",
  format: "truetype",
  src: font 
});

I am also unable to register fonts. code:

Font.register({ family: 'SourceSansPro', fonts: [
 { src: 'https://fonts.gstatic.com/s/sourcesanspro/v14/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lujVj9_mf.woff2' }, // font-style: normal, font-weight: normal
 { src: 'https://fonts.gstatic.com/s/sourcesanspro/v14/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmhdu3cOWxy40.woff2', fontWeight: 600 },
]});

code, variation 2:

Font.register({ family: 'SourceSansPro', fonts: [
 { src: 'https://fonts.googleapis.com/css2?family=Source+Sans+Pro&display=swap' }, // font-style: normal, font-weight: normal
 { src: 'https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@600&display=swap', fontWeight: 600 },
]});

console:

Error: Unknown font format
    at Object../node_modules/@react-pdf/fontkit/dist/fontkit.browser.es.js.fontkit$1.create (fontkit.browser.es.js:68)
    at FontSource._callee2$ (react-pdf.browser.es.js:2892)
    at tryCatch (runtime.js:63)
    at Generator.invoke [as _invoke] (runtime.js:293)
    at Generator.next (runtime.js:118)
    at asyncGeneratorStep (asyncToGenerator.js:3)
    at _next (asyncToGenerator.js:25)

UPDATE: I was able to get fonts to work using a .ttf url. If you’re using a google font you can do this by curling the google font url

➜  resume-builder-site git:(master) ✗ curl https://fonts.googleapis.com/css2\?family\=Source+Sans+Pro:wght@600\&display\=swap
@font-face {
  font-family: 'Source Sans Pro';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v14/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rAkA.ttf) format('truetype');
}

Taking the .ttf url that comes back, and put that into the src

Font.register({ family: 'SourceSansPro', fonts: [
 { src: 'https://fonts.gstatic.com/s/sourcesanspro/v14/6xK3dSBYKcSV-LCoeQqfX1RYOo3aPw.ttf' }, // font-style: normal, font-weight: normal
 { src: 'https://fonts.gstatic.com/s/sourcesanspro/v14/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rAkA.ttf', fontWeight: 600 },
]});

Figured it out with a huge help from my colleague. With typescript you need declarations.d.ts file in your src folder.

declare module "*.ttf" {
    const content: any;
    export default content;
}

declare module "*.otf" {
    const content: any;
    export default content;
}

If anyone still has an issue with font loading in Next.js, here is my workaround:

  1. Download ttf font and place somewhere in src folder (e.g. theme/fonts/pt-sans-regular.tff).
  2. If you use typescript add file fonts.d.ts in your typings folder with this content:
declare module "*.ttf";
  1. Modify next.config.js like this:
module.exports = {
  // ...
  webpack: (config) => {
    config.module.rules.push({
      test: /\.ttf$/i,
      type: "asset/resource",
    });
    return config;
  },
  // ...
};
  1. Register font like this:
import PTSansRegular from "theme/fonts/pt-sans-regular.ttf"; // use path according to file location and your project configuration.

Font.register({
  family: "PT Sans",
  fontStyle: "normal",
  fontWeight: "normal",
  fonts: [
    {
      src: PTSansRegular,
    },
  ],
});

Works fine for me with PDFDownloadLink, but not working properly with PDFViewer. With PDFViewer works only after navigating to a page where the viewer is placed, but after refresh font is not applied.

I had this issue as well. I was able to resolve it by importing the font file as a variable then using that as the src value.

import font from "./font.ttf"

Font.register({
  family: "FamilyName",
  format: "truetype",
  src: font 
});

Thank you!!! Why isn’t this in the docs?

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 am also unable to register fonts. code:

Font.register({ family: 'SourceSansPro', fonts: [
 { src: 'https://fonts.gstatic.com/s/sourcesanspro/v14/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lujVj9_mf.woff2' }, // font-style: normal, font-weight: normal
 { src: 'https://fonts.gstatic.com/s/sourcesanspro/v14/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwmhdu3cOWxy40.woff2', fontWeight: 600 },
]});

code, variation 2:

Font.register({ family: 'SourceSansPro', fonts: [
 { src: 'https://fonts.googleapis.com/css2?family=Source+Sans+Pro&display=swap' }, // font-style: normal, font-weight: normal
 { src: 'https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@600&display=swap', fontWeight: 600 },
]});

console:

Error: Unknown font format
    at Object../node_modules/@react-pdf/fontkit/dist/fontkit.browser.es.js.fontkit$1.create (fontkit.browser.es.js:68)
    at FontSource._callee2$ (react-pdf.browser.es.js:2892)
    at tryCatch (runtime.js:63)
    at Generator.invoke [as _invoke] (runtime.js:293)
    at Generator.next (runtime.js:118)
    at asyncGeneratorStep (asyncToGenerator.js:3)
    at _next (asyncToGenerator.js:25)

UPDATE: I was able to get fonts to work using a .ttf url. If you’re using a google font you can do this by curling the google font url

➜  resume-builder-site git:(master) ✗ curl https://fonts.googleapis.com/css2\?family\=Source+Sans+Pro:wght@600\&display\=swap
@font-face {
  font-family: 'Source Sans Pro';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(https://fonts.gstatic.com/s/sourcesanspro/v14/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rAkA.ttf) format('truetype');
}

Taking the .ttf url that comes back, and put that into the src

Font.register({ family: 'SourceSansPro', fonts: [
 { src: 'https://fonts.gstatic.com/s/sourcesanspro/v14/6xK3dSBYKcSV-LCoeQqfX1RYOo3aPw.ttf' }, // font-style: normal, font-weight: normal
 { src: 'https://fonts.gstatic.com/s/sourcesanspro/v14/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rAkA.ttf', fontWeight: 600 },
]});

Work fine for me!! Tysm 😄

I am having the same problem. I cannot get fonts to register with any of these methods and end up getting: × Unhandled Rejection (Error): Unknown font format

import RobotoBold from "./fonts/Roboto-Bold.ttf"
import RobotoRegular from "./fonts/Roboto-Regular.ttf"

Font.register({
  family: "Roboto-Regular",
  src: RobotoRegular,
})
Font.register({
  family: "Roboto-Bold",
  src: RobotoBold,
})`

The fonts are from here: https://fonts.google.com/specimen/Roboto?preview.text_type=custom

Has anyone fixed this? We have tried doing it with codes below. Still getting the same error.

import headingfont from "./BalooSemiBold.ttf";

Font.register({
  family: "Baloo",
  format: "truetype",
  src: headingfont,
});

<View style={(styles.section, { fontFamily: 'Baloo' })}>

Currently I solved the problem by creating an “assets” folder inside the “public” folder. Inside assets I placed my fonts and my images and it is working.

Font.register({family:"Montserrat", src: "/assets/Montserrat.ttf"})

This video was very useful! The solution is in min 7

Video

@DewangS Thanks same trouble here !

In case anyone encounters similar issue or any issue with font loading in fact, this may be helpful. It turned out the fonts I was trying to register had wrong metadata and pdf-react couldn’t recognise them as two different fonts. I have tried converting them from woff to ttf and back as some people were suggesting which didn’t help. At the end I ended up getting http://birdfont.org/ and editing the metadata and exporting the fonts in ttf format. Once I have done that registering of different weights and different fonts couldn’t be smoother.

It works!

In case anyone encounters similar issue or any issue with font loading in fact, this may be helpful. It turned out the fonts I was trying to register had wrong metadata and pdf-react couldn’t recognise them as two different fonts. I have tried converting them from woff to ttf and back as some people were suggesting which didn’t help. At the end I ended up getting http://birdfont.org/ and editing the metadata and exporting the fonts in ttf format. Once I have done that registering of different weights and different fonts couldn’t be smoother.

Has anyone got lucky with registering multiple custom fonts?

I have been trying something like this…

import Font1 from './font1.ttf';
import Font1Bold from './font1bold.ttf';
import Font2 from './font2.ttf';
import Font2Bold from './font2bold.ttf';

Font.register({
  family: 'Font1',
  fonts: [
    {
      src: Font1,
    },
    {
      src: Font1Bold,
      fontWeight: 800,
    },
  ],
});

Font.register({
  family: 'Font2',
  fonts: [
    {
      src: Font2,
    },
    {
      src: Font2Bold,
      fontWeight: 800,
    },
  ],
});

It’s always the font that is first being used in the document that is loaded correctly and the other one turns out muggled up. I don’t think it’s the font issue as I tried swapping them around in the document and the result is the same. See the images attached…

Screenshot 2021-01-20 at 09 15 24 Screenshot 2021-01-20 at 09 15 43

Can anyone tell me which font formats are acceptable? I know TrueType, any others?