How can I integrate custom fonts in Handlebars templates when using Puppeteer?

I have a Handlebars template that I am rendering to PDF using Puppeteer. I need guidance on how to implement custom fonts in this process.

At present, I have a static assets folder configured in my app.js file with the following line: app.use(express.static(path.join(__dirname, ‘assets’)));, which houses the necessary font files.

In my Handlebars template, I am including the fonts as follows:


  
  
  
    @font-face {
      font-family: 'OpenSans';
      src: url("../assets/fonts/OpenSans-Regular.ttf");
      font-style: normal;
    }

    @font-face {
      font-family: 'OpenSans';
      src: url("../assets/fonts/OpenSans-Italic.ttf");
      font-style: italic;
    }

    @font-face {
      font-family: 'OpenSans';
      src: url("../assets/fonts/OpenSans-Bold.ttf");
      font-weight: 600;
    }

    body {
      font-family: 'OpenSans';
      font-stretch: normal;
    }
  

However, when creating the PDF, the output uses a default font instead of the specified custom font.

Hey, maybe the path to font files is incorrect when puppeteer loads the template. Try using absolute paths insted of relative ones to ensure puppeteer can find your font files. You can use Node’s path module to construct the path based on your project directory.

Another common issue could be that the fonts are not being loaded due to the way Puppeteer handles CSS in its virtual browser instance. Make sure the font files are accessible over the network, not just locally. You might need to host them on a server where Puppeteer can fetch them during PDF generation. A workaround is to inline the fonts as base64-encoded strings in your CSS. This ensures that when Puppeteer renders the PDF, it has immediate access to the font data without requiring network access.

One thing that comes to mind is the sequence in which Puppeteer processes styles and rendering. Sometimes, if there’s any delay or issue in accessing the font files, Puppeteer might default to system fonts. To tackle this, try ensuring that Puppeteer waits for all network requests to complete before rendering. You can control this by adding a wait for network idle time in Puppeteer like so: await page.setDefaultNavigationTimeout(60000); or using page.waitForFunction. This provides ample time to fetch custom fonts if they’re hosted externally.