How to read a font file (ttf file) in a PdfDocument for Blazor WASM?

Hallo,

In a Blazor Web App which runs on the server I used the following code to read a font file (stored in wwwroot) in a Syncfusion.Pdf.PdfDocument:

var FontPath = Path.GetFullPath("wwwroot\\arial.ttf");
var fontStream = new FileStream(FontPath, FileMode.Open, FileAccess.Read);
var FontHeader = new Syncfusion.Pdf.Graphics.PdfTrueTypeFont(fontStream, 14, Syncfusion.Pdf.Graphics.PdfFontStyle.Bold);

When I use this code In a Blazor Wasm project it returns the next error:

System.IO.FileNotFoundException: Could not find file '/wwwroot\arial.ttf'.

Do you know how to load a font file in a Blazor Wasm project?



6 Replies

IJ Irfana Jaffer Sadhik Syncfusion Team November 21, 2025 01:35 PM UTC

Hi Vince,


The issue occurs because Blazor WebAssembly runs entirely in the browser, and it cannot directly access the server's file system (like wwwroot via Path.GetFullPath). In WASM, you need to load the font file as a static asset through an HTTP request instead of using FileStream.

Correct Approach for Blazor WASM

  1. Place the font file in wwwroot. For example: wwwroot/fonts/arial.ttf
  2. Load the font using HttpClient. In Blazor WASM, you can fetch the font file as a stream:


@inject HttpClient Http

@code {

    private async Task<Syncfusion.Pdf.Graphics.PdfTrueTypeFont> LoadFontAsync()

    {

        // Fetch the font file from wwwroot

        var fontStream = await Http.GetStreamAsync("fonts/arial.ttf");

 

        // Create the PdfTrueTypeFont

        var pdfFont = new Syncfusion.Pdf.Graphics.PdfTrueTypeFont(fontStream, 14, Syncfusion.Pdf.Graphics.PdfFontStyle.Bold);

        return pdfFont;

    }

}

 

  1. Use the font in your PDF generation logic

Call LoadFontAsync() before creating the PDF document.

Important Notes

  • Ensure the font file is marked as "Content" and "Copy to Output Directory" in your project settings.
  • We have attached the Blazor WASM sample for your reference, please try the below sample in your end and let us know the result. 

Please refer this below documentation,
https://www.syncfusion.com/faq/blazor/web-api/how-do-i-read-static-or-local-files-in-blazor-webassembly


Note: Run the application --> Go to Fetch Data page --> Click Export to PDF button to download the pdf document.


Please let us know if you need any further assistance in this.



Regards,

Irfana J.


Attachment: PDF_WASM_Sample1242392479_fbff17f1.zip


VI Vince November 21, 2025 03:39 PM UTC

Hallo,


Thanks for your reply.


In your attached sample you are using in your Program.cs file the next code:

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });


In my project I have to make a API call so in my Program.cs file I use:

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https://localhost:7083/") });


Because of this a receive the next error when calling the code line

byteOfTheFile = await Http.GetByteArrayAsync("Fonts/ARIALUNI.ttf") in FetchData.razor;

:

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: TypeError: Failed to fetch
System.Net.Http.HttpRequestException: TypeError: Failed to fetch


How do I have to change the code?




JT Jeyalakshmi Thangamarippandian Syncfusion Team November 24, 2025 03:09 PM UTC

Hi vince,


Thank you for the details.
 
In the sample, builder.HostEnvironment.BaseAddress points to the same origin where your Blazor app is hosted (for example, https://localhost:5001/). That’s why the call
await Http.GetByteArrayAsync("Fonts/ARIALUNI.ttf")
works correctly — it retrieves the static font file bundled with the app.
However, when you hard‑code
BaseAddress = new Uri("https://localhost:7083/")
all relative requests (such as "Fonts/ARIALUNI.ttf") are redirected to the API server (https://localhost:7083/Fonts/ARIALUNI.ttf). Since the API server does not host that font file, the request fails with TypeError: Failed to fetch.
 
There are two possible approaches:
  1. Run the Blazor app on the same port as your API by updating the launchSettings.json configuration.
  2. Keep separate origins but configure two HttpClient instances:
    • One for API calls (https://localhost:7083/).
    • One for static file requests from the Blazor app’s origin (builder.HostEnvironment.BaseAddress).
Program.cs
// Default HttpClient for static files and same-origin requests
builder.Services.AddScoped(sp =>
    new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

// Named HttpClient for your API
builder.Services.AddHttpClient("MyApi", client =>
{
    client.BaseAddress = new Uri("https://localhost:7083/");
});
 
Usage in components
@inject HttpClient Http              // default client (static files)
@inject IHttpClientFactory ClientFactory

private async Task ExportPdfAsync()
{
    byte[] bytes = await GetFontFromApiAsync();

    if (bytes == null)
    {
        // Fallback to static file
        bytes = await Http.GetByteArrayAsync("Resources/ARIALUNI.TTF");
    }
}
 
Helper method
private async Task<byte[]> GetFontFromApiAsync()
{
    try
    {
        var apiClient = ClientFactory.CreateClient("MyApi");
        var response = await apiClient.GetAsync("api/values");

        if (response.IsSuccessStatusCode)
        {
            var data = await response.Content.ReadAsStringAsync();
            return Convert.FromBase64String(data);
        }
        else
        {
            Console.WriteLine($"API returned error: {response.StatusCode}");
            return null;
        }
    }
    catch (HttpRequestException ex)
    {
        Console.WriteLine($"API call failed: {ex.Message}");
        return null;
    }
}
 
We have attached the modified sample for your reference. Please try this setup in your environment and let us know if you need further assistance.
 Regards,

Jeyalakshmi T

 

Attachment: BlazorSampleWASM_7299736b.zip


VI Vince November 24, 2025 07:14 PM UTC

Hallo,


Thanks for your reply.


I implemented your solution and it's working great now!


What I don't understand in a Blazor WASM project is, why a font file needs to be downloaded using "bytes = await Http.GetByteArrayAsync("Resources/ARIALUNI.TTF");" but images - which are also stored in wwwroot - are immediatly shown using your SfCarousel component with code "<img src="images/big.png" />"?



IJ Irfana Jaffer Sadhik Syncfusion Team November 25, 2025 11:28 AM UTC

Hi Vince,


In our PDF library, fonts and images are not automatically accessible in the same way as UI components in Blazor. The library is a non‑UI backend component, so it does not interact directly with UI elements or provide built‑in mechanisms to fetch resources like fonts or images. Instead, these files need to be explicitly read and passed into the library for processing.

Additionally, the library is designed to work consistently across multiple .NET platforms—not just Blazor WASM—including Blazor Server, ASP.NET Core, and environments on Windows, Linux, and macOS. This cross‑platform design ensures flexibility, but it also means that resource handling (such as loading fonts or images) must be managed by the application and then supplied to the library.


Regards,

Irfana J.






VI Vince November 25, 2025 11:43 AM UTC

Thanks for your explanation!


Loader.
Up arrow icon