Use the URL to PDF Converter when you want the file without installing anything. The steps below are the detail.
The free way to convert HTML to PDF in C# with current CSS is Chromium. Playwright for .NET drives that browser, and PdfAsync writes the file. Paid libraries such as IronPDF, SelectPdf, Aspose, and Syncfusion show up for the same search. They are a different product. This page is the Playwright script.
Install Playwright and Chromium
Create a console project, add the package, and build. The build copies playwright.ps1 into the output directory. Run that script to install Chromium. The folder name matches your target framework, so it might be net8.0 or something newer.
dotnet new console -n HtmlToPdf
cd HtmlToPdf
dotnet add package Microsoft.Playwright
dotnet build
pwsh bin/Debug/net8.0/playwright.ps1 install chromium
If the framework folder is not net8.0, use the folder dotnet build actually created.
Convert an HTML string
PdfAsync uses print CSS unless you set the media type first. PrintBackground defaults to false. Format defaults to Letter. Margins default to zero. This saves an A4 PDF with backgrounds and a 12mm margin.
using Microsoft.Playwright;
var html = """
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body { font-family: sans-serif; font-size: 12pt; }
h1 { background: #eef2ff; padding: 8px; }
</style>
</head>
<body>
<h1>October report</h1>
<p>Generated with Playwright for .NET.</p>
</body>
</html>
""";
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();
await page.SetContentAsync(html);
await page.PdfAsync(new PagePdfOptions
{
Path = "report.pdf",
Format = "A4",
PrintBackground = true,
Margin = new Margin
{
Top = "12mm",
Right = "12mm",
Bottom = "12mm",
Left = "12mm"
}
});
The raw string needs a current C# language version. A normal string works on older compilers. PdfAsync also returns the PDF bytes if you omit Path.
Convert a public URL
The URL has to be public. This does not log in, and it does not bypass a paywall.
await page.GotoAsync("https://example.com", new PageGotoOptions
{
WaitUntil = WaitUntilState.DOMContentLoaded
});
await page.PdfAsync(new PagePdfOptions { Path = "page.pdf", Format = "A4" });
Print CSS and screen CSS
The .NET docs generate a screen-media PDF by calling EmulateMediaAsync before PdfAsync:
await page.EmulateMediaAsync(new PageEmulateMediaOptions { Media = Media.Screen });
await page.PdfAsync(new PagePdfOptions { Path = "report.pdf", Format = "A4", PrintBackground = true });
Skip that call when you want @media print. Those rules are the same ones in print from CSS to PDF. PreferCSSPageSize defaults to false, so an @page { size } rule loses to Format until you set it true.
Add page numbers
Header and footer templates do not see the page stylesheet, and script tags inside them do not run. Give the footer an explicit font size. An empty header has to be an element, or Chromium inserts the date and the title. Widen the bottom margin so the footer has room.
await page.PdfAsync(new PagePdfOptions
{
Path = "report.pdf",
Format = "A4",
DisplayHeaderFooter = true,
HeaderTemplate = "<span></span>",
FooterTemplate = "<div style='font-size:10px; width:100%; text-align:center;'><span class='pageNumber'></span> / <span class='totalPages'></span></div>",
Margin = new Margin { Top = "12mm", Right = "12mm", Bottom = "18mm", Left = "12mm" }
});
The classes Chromium fills are date, title, url, pageNumber, and totalPages. Chromium does not draw CSS @page margin boxes.
Paid libraries, and PuppeteerSharp
IronPDF, SelectPdf, Aspose, and Syncfusion sell a packaged engine and a license. iText’s pdfHTML add-on, including the old iTextSharp samples, is AGPL or commercial. None of that is required for the script above.
PuppeteerSharp is the other free Chromium port for .NET. It is the same idea as HTML to PDF in Node with Puppeteer. One of the two free browsers is enough. This URL is the Playwright one, which also covers a search for HTML to PDF in .NET.
Skip the install
The URL to PDF converter runs headless Chrome on a public URL or on pasted HTML. It uses screen media, skips print-only rules, and takes the paper size from the form. The file is deleted after download. There is no signup and no watermark.









