How to Convert HTML to PDF with Syncfusion
Convert URLs, files, and HTML strings to PDFs in .NET with Syncfusion Blink, including JavaScript, fonts, Linux deployment, and troubleshooting.
Syncfusion converts HTML to PDF in .NET with its Chromium-based Blink rendering engine. Install the package for your application, create an HtmlToPdfConverter, call Convert, and save the returned PdfDocument.
Minimal URL-to-PDF example
For a public page, this is the smallest complete C# program:
using Syncfusion.HtmlConverter;
using Syncfusion.Pdf;
HtmlToPdfConverter htmlConverter = new HtmlToPdfConverter();
using (PdfDocument document = htmlConverter.Convert("https://example.com"))
{
document.Save("Output.pdf");
}
Install the Syncfusion HTML-to-PDF package that matches your target application and platform. The Windows package used in Syncfusion’s examples is Syncfusion.HtmlToPdfConverter.Net.Windows. The converter is documented for Windows Forms, WPF, ASP.NET, ASP.NET MVC, and ASP.NET Core applications.
1. Install the correct NuGet package
Package selection follows the host application and operating system. For an ASP.NET Core application targeting .NET 8 or later, Syncfusion documents Syncfusion.HtmlToPdfConverter.Net.Windows. Use the corresponding Syncfusion package for other supported application types.
dotnet add package Syncfusion.HtmlToPdfConverter.Net.Windows
Current Blink package guidance says the required Blink binaries are copied automatically in the documented version line. BlinkPath remains available when you need to point to a custom binary location.
2. Convert different kinds of input
Public URL
using Syncfusion.HtmlConverter;
using Syncfusion.Pdf;
var converter = new HtmlToPdfConverter();
using var pdf = converter.Convert("https://example.com/invoice");
pdf.Save("invoice.pdf");
Local HTML file
using Syncfusion.HtmlConverter;
using Syncfusion.Pdf;
var converter = new HtmlToPdfConverter();
using var pdf = converter.Convert(@"C:\reports\invoice.html");
pdf.Save(@"C:\reports\invoice.pdf");
Local stylesheets, scripts, images, and fonts referenced by that file require local file access. Enable it through the Blink settings when your document uses local resources.
HTML string with relative assets
using Syncfusion.HtmlConverter;
using Syncfusion.Pdf;
var html = """
<!doctype html>
<html>
<head>
<link rel=\"stylesheet\" href=\"css/invoice.css\">
</head>
<body><h1>Invoice 1042</h1></body>
</html>
""";
var converter = new HtmlToPdfConverter();
// Supply a base URL so css/invoice.css and other relative paths resolve.
using var pdf = converter.Convert(html, "https://example.com/reports/");
pdf.Save("invoice.pdf");
When converting an HTML string, provide a base URL for relative images, CSS, scripts, and fonts. Without it, those resources commonly appear missing in the PDF.
SVG, MHTML, authenticated, GET, and POST content
The same converter supports SVG and MHTML inputs, authenticated pages, and content retrieved with HTTP GET or POST. Configure the request and authentication details in the Blink converter settings appropriate to your application before calling Convert.
3. Configure Blink for accurate output
Blink renders modern HTML, CSS, and JavaScript. The settings below control the differences developers most often see between a browser tab and the generated PDF.
JavaScript
Blink supports JavaScript. Use BlinkConverterSettings.EnableJavaScript to enable or disable execution. It is enabled by default in the documented example. Disable it for static, untrusted input when scripts are not needed; keep it enabled for client-rendered applications.
Wait for asynchronous pages
Single-page applications and charts may render after the initial response. Have the page set window.status = "completed" when it is ready, then configure the converter to wait for that status. This is more deterministic than guessing with a fixed delay.
<script>
renderReport().then(() => {
window.status = "completed";
});
</script>
Screen versus print CSS
Choose the media type that matches your stylesheet. Print media may hide navigation and change colors, while screen media may preserve an on-screen dashboard layout. Set the viewport dimensions explicitly when responsive breakpoints affect the result.
Fonts and external resources
Wait for external fonts before conversion when typography affects pagination. Ensure the conversion host can resolve every stylesheet, image, script, and font URL. A blocked resource can change line wrapping and move content onto another page.
Margins, paper, orientation, and page ranges
Set PDF page size, margins, and landscape orientation in the Blink/PDF settings for your target document. For long reports, configure page ranges when you only need selected pages. Keep header and footer space in mind when calculating printable content height.
Inject JavaScript before rendering
BlinkConverterSettings.JavaScript injects JavaScript into the input HTML or URL before Blink renders it. Use this to expand accordions, select a tab, add a print-only class, or signal readiness without changing the source site.
Local file access
EnableLocalFileAccess controls whether local CSS, JavaScript, images, and fonts referenced by HTML can load. Enable it for trusted files that depend on local assets. Keep the input directory controlled by your application.
Table of contents
Set EnableToc to build a table of contents from headings h1 through h6. Use a consistent heading hierarchy so the generated entries are useful.
4. A configurable C# example
The exact property names can vary by Syncfusion package version, so check the API reference for the version installed in your project. The following shows the configuration decisions to make in one place:
using Syncfusion.HtmlConverter;
using Syncfusion.Pdf;
var settings = new BlinkConverterSettings
{
EnableJavaScript = true,
EnableLocalFileAccess = true,
// Configure viewport, media type, margins, waiting, JavaScript,
// BlinkPath, and TOC according to your installed package version.
};
var converter = new HtmlToPdfConverter
{
ConverterSettings = settings
};
using var document = converter.Convert("https://example.com/report");
document.Save("report.pdf");
Use the same pattern for a local file or HTML string. For an HTML string with relative assets, pass a base URL to Convert.
5. ASP.NET Core usage
Keep conversion work out of the request thread when documents are large or pages execute substantial JavaScript. A background worker can generate the PDF, store it, and let the HTTP request return a job identifier. For small documents, a direct endpoint can stream the resulting bytes:
using Syncfusion.HtmlConverter;
using Syncfusion.Pdf;
app.MapGet("/pdf", () =>
{
var converter = new HtmlToPdfConverter();
using var document = converter.Convert("https://example.com");
using var stream = new MemoryStream();
document.Save(stream);
return Results.File(stream.ToArray(), "application/pdf", "page.pdf");
});
Register the Syncfusion license key during application startup when required by your license and package setup. Trial assemblies or NuGet usage under Syncfusion’s documented guidance require a license key.
6. Deployment checklist
- Install the package matching the target framework and host.
- For Linux conversion, install
libgbm1; Syncfusion documents this dependency from version 20.1.0.55. - Verify that Blink binaries are present, or set
BlinkPathto a custom location. - Register the required Syncfusion license key before production conversion.
- Allow outbound access to every asset host used by the page.
- Use a writable temporary directory if the runtime or container needs one.
- Run conversion under a restricted service identity and accept only trusted local files when local access is enabled.
7. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Blank or nearly empty PDF | JavaScript content has not rendered, or the page is blocked. | Enable JavaScript, add a readiness signal with window.status, and verify the conversion host can reach the URL. |
| Images or CSS are missing | Relative URLs have no base URL, or local access is disabled. | Pass a base URL for HTML strings and enable EnableLocalFileAccess for trusted local assets. |
| Wrong responsive layout | Viewport dimensions or media type differ from the browser. | Set the viewport and choose screen or print media explicitly. |
| Fonts fall back | Font files are unavailable or conversion starts before fonts load. | Make font URLs reachable, wait for font loading, and check container font support. |
| Charts or SPA components are absent | Rendering is asynchronous. | Signal completion from page JavaScript and configure the corresponding wait setting. |
| Local file security error | Local file access is disabled. | Enable it only for trusted input and verify the referenced paths. |
| Linux startup failure | Required system library is missing. | Install libgbm1 and confirm the Blink binaries match the runtime architecture. |
| License exception | A license key is missing for the selected package or trial setup. | Register the Syncfusion key during startup according to the package documentation. |
| Conversion hangs or times out | The page waits for a never-ending request or readiness signal. | Remove blocked dependencies, set a bounded wait, and ensure your completion signal always executes. |
8. Performance, reliability, and cost considerations
- Rendering cost: JavaScript-heavy pages, large images, web fonts, and long documents take more CPU and memory than static HTML.
- Concurrency: Limit parallel conversions to the memory available to the host. Queue large jobs instead of starting unbounded browser instances.
- Repeatability: Pin package versions, use fixed viewport and media settings, and make external assets deterministic where possible.
- Network reliability: A PDF depends on every remote resource loading during conversion. Host critical assets reliably or inline them for self-contained documents.
- Output validation: Check that the file exists, has a nonzero length, and contains expected page content before returning it to a user.
- Licensing: Include Syncfusion licensing in the deployment plan; the converter is not a license-free runtime component under the documented trial/NuGet guidance.
Or skip the browser setup
If you only need a clean screenshot or PDF from a URL, ScreenshotNeo provides a hosted capture API and MCP server. It accepts the cookie or consent banner like a visitor, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and lets you turn each cleanup step off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers identify the page verdict and whether the request was billed.
See the ScreenshotNeo API documentation for all options. A one-call WebP capture looks like this:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also supports PDF output, full-page and element capture, custom CSS and JavaScript, headers and cookies, device and viewport settings, waits, blocking rules, caching, bulk capture, signed links, asynchronous jobs, and an MCP server for AI agents. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
FAQ
Does Syncfusion execute JavaScript?
Yes. Blink supports JavaScript, and EnableJavaScript controls execution.
Can I convert an HTML string?
Yes. Pass the string and a base URL when it contains relative resources.
Why does my PDF differ from Chrome?
Viewport size, print versus screen CSS, font loading, JavaScript timing, and unavailable network resources can all change layout.
Do I need extra software on Linux?
Yes. Syncfusion documents libgbm1 as a Linux dependency from version 20.1.0.55, along with the Blink runtime.
Can I generate a table of contents?
Enable EnableToc; headings from h1 through h6 become entries.


