DEV Community

IronSoftware
IronSoftware

Posted on

How to Use Web Fonts and Icons in PDFs with C#

Generating PDFs with custom fonts and icon fonts used to be painful. I'd render an HTML page with beautiful typography, convert it to PDF, and watch all the fonts revert to Times New Roman. Or worse — blank pages where fonts didn't load.

IronPDF changed this. You can use Google Fonts, FontAwesome icons, and custom fonts in PDFs exactly as they appear in your browser.

using IronPdf;
// Install via NuGet: Install-Package IronPdf

var html = @"
<link href='https://fonts.googleapis.com/css?family=Lobster' rel='stylesheet'>
<p style='font-family: Lobster, serif; font-size: 30px;'>Hello Google Fonts!</p>
";

var renderer = new [ChromePdfRenderer](https://ironpdf.com/blog/videos/how-to-render-html-string-to-pdf-in-csharp-ironpdf/)();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(2000);
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("fonts.pdf");
Enter fullscreen mode Exit fullscreen mode

The key is WaitFor.AllFontsLoaded(2000) — it waits up to 2 seconds for fonts to download before rendering.

Why Do Fonts Fail in PDFs?

When you convert HTML to PDF, the rendering engine needs to download external fonts. If the PDF renders before fonts finish loading, you get:

  • Fallback fonts (Arial, Times New Roman)
  • Blank pages
  • Missing text

I spent hours debugging a production issue where customer invoices had blank company names. The custom brand font wasn't loading in time. Adding WaitFor.AllFontsLoaded() fixed it instantly.

How Do I Use Google Fonts in PDFs?

Include the font stylesheet and wait for it to load:

var html = @"
<link href='https://fonts.googleapis.com/css?family=Roboto:400,700' rel='stylesheet'>
<style>
    body { font-family: 'Roboto', sans-serif; }
    h1 { font-weight: 700; }
    p { font-weight: 400; }
</style>
<h1>Heading with Roboto Bold</h1>
<p>Paragraph with Roboto Regular</p>
";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(3000);  // 3 seconds max
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("roboto.pdf");
Enter fullscreen mode Exit fullscreen mode

You can use any font from Google Fonts. Just grab the <link> tag from the Google Fonts website and paste it into your HTML.

I use Roboto for corporate reports, Lato for marketing materials, and Lobster for event invitations. The PDFs look exactly like the web previews.

How Do I Add Icon Fonts Like FontAwesome?

Same pattern — link the stylesheet and wait:

var html = @"
<link href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css' rel='stylesheet'>
<i class='fa fa-check' style='font-size: 24px; color: green;'></i> Task Complete
<br>
<i class='fa fa-times' style='font-size: 24px; color: red;'></i> Task Failed
";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(2000);
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("icons.pdf");
Enter fullscreen mode Exit fullscreen mode

Icons scale beautifully because they're vector fonts. I use this for:

  • Checkboxes and status indicators in reports
  • Social media icons in resumes
  • Dashboard alerts in analytics PDFs

Can I Use Custom Font Files?

Yes, with the @font-face CSS rule:

var html = @"
<!DOCTYPE html>
<html>
<head>
<style>
@font-face {
    font-family: 'MyCustomFont';
    src: url('fonts/MyCustomFont.ttf');
}
body {
    font-family: 'MyCustomFont', serif;
    font-size: 20px;
}
</style>
</head>
<body>
<p>This uses a custom font file.</p>
</body>
</html>
";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(2000);
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("custom.pdf");
Enter fullscreen mode Exit fullscreen mode

The font file path is relative to your HTML. Make sure the file is accessible when rendering.

I built a white-label invoice system where each client had custom brand fonts. We stored .ttf files in blob storage and referenced them in the HTML template.

What If My Font Files Are Hosted Remotely?

Use absolute URLs:

@font-face {
    font-family: 'BrandFont';
    src: url('https://cdn.example.com/fonts/brand.woff2') format('woff2');
}
Enter fullscreen mode Exit fullscreen mode

This works as long as the server is publicly accessible when the PDF renders.

For private fonts, use base64 encoding to embed them directly:

var fontBytes = File.ReadAllBytes("MyFont.ttf");
var base64Font = Convert.ToBase64String(fontBytes);

var html = $@"
<style>
@font-face {{
    font-family: 'EmbeddedFont';
    src: url(data:font/truetype;charset=utf-8;base64,{base64Font}) format('truetype');
}}
body {{ font-family: 'EmbeddedFont'; }}
</style>
<p>Font embedded as base64</p>
";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("embedded.pdf");
Enter fullscreen mode Exit fullscreen mode

The font is part of the HTML, so no external file access needed. I use this for deployment scenarios where file paths are unpredictable.

How Long Should I Wait for Fonts?

Start with 2000ms (2 seconds). Increase if you have slow networks or many fonts:

renderer.RenderingOptions.WaitFor.AllFontsLoaded(5000);  // 5 seconds for slow connections
Enter fullscreen mode Exit fullscreen mode

If fonts still don't load, the timeout expires and rendering proceeds with fallback fonts. Check your network access and font URLs.

I set longer timeouts (5-10 seconds) for background jobs where speed doesn't matter. For user-facing PDF downloads, I keep it under 3 seconds to avoid noticeable delays.

What About Multiple Fonts and Icons Together?

Combine them in one HTML document:

var html = @"
<link href='https://fonts.googleapis.com/css?family=Roboto:400,700' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Lora' rel='stylesheet'>
<link href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css' rel='stylesheet'>

<style>
    h1 { font-family: 'Roboto', sans-serif; font-weight: 700; }
    p { font-family: 'Lora', serif; }
</style>

<h1><i class='fa fa-file-pdf'></i> Invoice Report</h1>
<p>Thank you for your business.</p>
";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(3000);
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("multi-fonts.pdf");
Enter fullscreen mode Exit fullscreen mode

IronPDF waits for all fonts before rendering. I built a dashboard PDF that uses 3 Google Fonts plus Bootstrap icons — all render perfectly.

Does This Work on Azure?

Yes, with caveats. On Azure Shared Web App tiers, SVG fonts don't work. Use TrueType (.ttf) or WOFF (.woff, .woff2) instead.

For Standard/Premium tiers and Azure Web Roles, all font formats work.

I deployed a PDF generation service to Azure App Service (Standard tier) with no font issues. Just make sure your font CDN is accessible from Azure's network.

How Do I Troubleshoot Font Loading Issues?

If fonts don't appear in the PDF:

  1. Check the font URL — Visit it in a browser to confirm it's accessible
  2. Increase timeout — Try 5000ms or 10000ms
  3. Use developer tools — Render the HTML in a browser and check the Network tab for font 404s
  4. Check CSS syntax — Typos in font-family break rendering
  5. Test locally first — Verify fonts work in a browser before generating PDFs

I debug font issues by saving the HTML to a file and opening it in Chrome. If fonts don't load there, they won't load in the PDF.

Can I Use Variable Fonts?

Yes, IronPDF's Chromium engine supports modern font features:

var html = @"
<link href='https://fonts.googleapis.com/css2?family=Roboto+Flex:wght@100..900' rel='stylesheet'>
<style>
    p { font-family: 'Roboto Flex', sans-serif; font-weight: 300; }
</style>
<p>Lightweight Roboto Flex at 300 weight</p>
";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(2000);
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("variable-font.pdf");
Enter fullscreen mode Exit fullscreen mode

Variable fonts let you fine-tune weight, width, and other attributes. Great for branding consistency.

Quick Reference

Font Type Method Wait Required?
Google Fonts <link> to stylesheet Yes
FontAwesome Icons <link> to CDN Yes
Custom .ttf/.woff @font-face with file path Yes
Base64 embedded @font-face with data URI No (inline)
System fonts CSS font-family No

Key Principles:

  • Always use WaitFor.AllFontsLoaded() for external fonts
  • Test HTML in a browser first to verify font loading
  • Use base64 embedding for fonts that must be self-contained
  • Increase timeout for slow networks or many fonts

The complete guide to fonts in PDFs covers additional scenarios like font subsetting and embedding.


Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.

Top comments (0)