EvoPdf Classic → EvoPdf Next

Migrating an HTML to PDF integration from Classic to Next

The class is still called HtmlToPdfConverter and the shape of a conversion — create, set options, call ConvertUrl or ConvertHtml — is the same. What changes is the rendering engine behind it, and with it the way the PDF page is sized and the way headers and footers are described. This guide lists the differences you will actually hit, with the Classic and Next code side by side. Your existing HTML to PDF license covers both editions.

Unchanged

What stays the same

The conversion calls

  • ConvertUrl(url), ConvertHtml(html, baseUrl), the …ToFile variants
  • One converter instance per conversion
  • ConversionDelay, NavigationTimeout

The option groups

  • HtmlViewerWidth, HtmlViewerHeight, HtmlViewerZoom
  • PdfDocumentOptions with PdfPageSize, PdfPageOrientation, margins in points
  • Security, viewer preferences, digital signatures

Licensing

  • The HTML to PDF license and the Toolkit license cover Classic and Next
  • Same key, set in a different place (see below)
  • Demo mode without a key, with watermarked output

Authentication, redirects, cookies

Step 1

Packages, namespace, license key

Replace the Classic package with the Next package for your deployment target, change the using, and move the license key from the converter instance to the static Licensing class.

Classic
using EvoPdf;

var converter = new HtmlToPdfConverter();
converter.LicenseKey = "…";
converter.ConversionDelay = 2;
byte[] pdf = converter.ConvertUrl(url);
using EvoPdf.Next;

Licensing.LicenseKey = "…";   // once per process
var converter = new HtmlToPdfConverter();
converter.ConversionDelay = 2;
byte[] pdf = converter.ConvertUrl(url);
Next is a .NET Standard 2.0 library with a platform-specific runtime inside the package: EvoPdf.Next.HtmlToPdf.Windows, .Linux, .MacOS, or the .Arm64 variants. Windows and macOS need nothing else; on Linux a few system packages are required — see Getting Started on Linux. Classic runs on Windows only.
Step 2

The page sizing model is different

This is the change most likely to alter the look of your PDFs, because the two editions start from opposite defaults.

Classic

HtmlViewerWidth is the browser window width in pixels, and the HTML is laid out at that width. The PDF page is PdfPageSize — A4 by default — and, because FitWidth is true by default, the rendered content is scaled down to fit the fixed page width. With FitWidth = false, AutoSizePdfPage instead grows the page to show the content unscaled; ClipHtmlView forces the content to exactly the viewer width.

converter.HtmlViewerWidth = 1024;
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
converter.PdfDocumentOptions.FitWidth = true;      // default
converter.PdfDocumentOptions.AutoSizePdfPage = true;

HtmlViewerWidth (default 1024 px) is again the viewport width — but by default the PDF page width is derived from it: AutoResizePdfPageWidth is true, so the page width becomes HtmlViewerWidth × 0.75 points (768 pt for 1024 px, plus any margins), while the page height still comes from PdfPageSize. Content wider than the viewer is scaled down to the page. To get an exact A4 page as in Classic, turn the auto width off.

converter.HtmlViewerWidth = 1024;
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
// default: page width = 1024 × 0.75 = 768 pt, height from A4
converter.PdfDocumentOptions.AutoResizePdfPageWidth = false; // exact A4
converter.PdfDocumentOptions.AutoResizePdfPageHeight = false;

Reflowing pages vs. fixed-width pages

If your HTML reflows with the viewport — fluid layouts, percentages, responsive CSS — HtmlViewerZoom works as in a browser: CSS pixels are scaled, so text and pixel-sized images grow or shrink with the zoom. If the page has a fixed overall width — a main container with an explicit width — Next may adjust the output to fit the PDF page width within a certain zoom range; outside that range the content is scaled proportionally, and above the upper limit anything beyond the right edge of the page is truncated. In Classic the same page would simply have been scaled down by FitWidth.

Practical rule

Set HtmlViewerWidth to the width your page is designed for, and decide once whether you want the page to follow the content (keep AutoResizePdfPageWidth = true) or the content to follow the page (false, plus a standard PdfPageSize). Start with the second when replacing Classic — it is the closest to what your users see today — and compare a few documents before switching the default. AutoResizePdfPageHeight = true is the Next equivalent of Classic's single-page output. Details: HTML to PDF Converter Options.

Step 3

Headers and footers are described as HTML, not drawn as elements

In Classic a header is a container you add elements to — HtmlToPdfElement, TextElement, LineElement — with per-page visibility decided in the PrepareRenderPdfPageEvent handler. In Next a header is an HTML document with its own options object; page numbers are variables inside that HTML and per-page visibility is three booleans.

Classic
converter.PdfDocumentOptions.ShowHeader = true;
converter.PdfHeaderOptions.HeaderHeight = 60;
converter.PdfHeaderOptions.HeaderBackColor = Color.White;

HtmlToPdfElement headerHtml = new HtmlToPdfElement(headerUrl);
headerHtml.FitHeight = true;
converter.PdfHeaderOptions.AddElement(headerHtml);

// line under the header
LineElement line = new LineElement(0, 59, headerWidth, 59);
line.ForeColor = Color.Gray;
converter.PdfHeaderOptions.AddElement(line);

// page numbers: a TextElement with &p; and &P; placeholders
converter.PdfFooterOptions.AddElement(
    new TextElement(0, 20, "Page &p; of &P;", font));

// hide on the first page, from an event handler
converter.PrepareRenderPdfPageEvent += (p) =>
    { if (p.PageNumber == 1) p.Page.ShowHeader = false; };
var header = converter.PdfDocumentOptions.PdfHtmlHeader;

header.HtmlSourceUrl = headerUrl;        // or header.Html + HtmlBaseUrl
header.Height = 60;                      // or AutoSizeContentHeight = true
header.FitHeight = true;
header.AutoResizePdfMargins = true;   // make room in the top margin

// line under the header: CSS in the header HTML

// page numbers: variables in the footer HTML
converter.PdfDocumentOptions.PdfHtmlFooter.Html =
    "<div style=\"text-align:center\">Page {page_number} of {total_pages}</div>";

// per-page visibility: no event handler
header.ShowInFirstPage = false;
header.ShowInOddPages = true;
header.ShowInEvenPages = true;
header.ReserveSpaceAlways = true;   // keep the space on hidden pages
Anything you drew with TextElement, ImageElement or LineElement becomes markup in the header or footer HTML. Header and footer HTML is rendered by the same engine as the page, so web fonts, CSS and images work there too. Full sample: HTML Header and Footer with Page Numbers.
Reference

Option map

ClassicNextNote
using EvoPdf;using EvoPdf.Next;Namespace
converter.LicenseKeyLicensing.LicenseKeyStatic, set once
PdfDocumentOptions.FitWidth = true (default)PdfDocumentOptions.AutoResizePdfPageWidth = falseContent fits a fixed page width
PdfDocumentOptions.AutoSizePdfPagePdfDocumentOptions.AutoResizePdfPageWidth = true (default)Page width follows the viewer width
PdfDocumentOptions.SinglePagePdfDocumentOptions.AutoResizePdfPageHeight = true (with AutoResizePdfPageWidth = true)Whole content on one page
PdfDocumentOptions.ShowHeader + PdfHeaderOptionsPdfDocumentOptions.PdfHtmlHeaderSame for footer
PdfHeaderOptions.HeaderHeightPdfHtmlHeader.Height / AutoSizeContentHeightMin/Max content height available
PdfHeaderOptions.AddElement(HtmlToPdfElement)PdfHtmlHeader.Html or HtmlSourceUrlOne HTML document per header/footer
TextElement with &p; / &P;{page_number} / {total_pages} in the HTMLSkipVariablesParsing when not used
PdfFooterOptions.PageNumberingStartIndexPdfHtmlFooter.PageNumberOffset / TotalPagesOffsetOffsets for the page counters
PrepareRenderPdfPageEventPage.ShowHeaderPdfHtmlHeader.ShowInFirstPage / ShowInOddPages / ShowInEvenPagesNo event handler
PdfDocumentOptions.TopSpacing / YPdfHtmlHeader.AutoResizePdfMarginsHeader space added to the top margin
ClipHtmlView, StretchToFitNo direct equivalent: the PDF page width follows HtmlViewerWidth (AutoResizePdfPageWidth, default true), so clipping or stretching the viewer content is not needed
Engine behavior

Beyond the API: what the new rendering engine changes in layout, fonts, JavaScript and image loading

Both engines render with the screen media type by default and both expose MediaType, so that part does not change. What changes is the engine underneath: Next renders exactly like a current Chrome, so pages look the way your browser shows them — and a few things Classic handled its own way now follow the browser.

Layout follows current web standards

  • Flexbox, CSS grid, custom properties, modern selectors and ES2015+ JavaScript render as in Chrome — layouts that carried workarounds for the old engine can drop them, and pages that looked "acceptable" only because a rule was ignored may now look different
  • Print CSS is honored: @page, break-before/after/inside, page-break-*, so page breaks you controlled from the API can move into the stylesheet
  • Content is laid out at 96 DPI; the PDF page width follows HtmlViewerWidth unless you fix it (see step 2)

Text and fonts

  • Font fallback, hinting and metrics are Chrome's — line breaks, and therefore page breaks, can shift by a line compared with Classic output on the same document
  • Web fonts (including WOFF2) are downloaded and embedded as subsets; PDFs with many fonts or large images can differ in size from Classic output
  • Text stays selectable and searchable; with PDF/UA output it is also tagged

JavaScript and dynamic content

  • Scripts run in a real browser engine: charts, frameworks and async data that the old engine could not execute now render — and pages that finish loading late need ConversionDelay or TriggeringMode, as before
  • JavaScriptEnabled, NavigationTimeout and HtmlViewerWidth keep their role

Resources and security defaults

  • Lazy-loaded images are fetched by default (LoadLazyImages); images that the old engine skipped will appear
  • Local files, insecure content and blocked hosts are governed by explicit options (LocalFilesEnabled and the template-level equivalents) — check them if your HTML references file paths or mixed content
  • Sites served only over HTTP/2 or TLS 1.3 load directly — no need to download the HTML yourself and convert it as a string, as some Classic integrations did

Suggested order: run the Next demo application on your own pages first (online or the downloaded project), settle the page sizing options on two or three representative documents, then port the headers and footers. Most integrations need changes in exactly those two places and nowhere else.

Try your pages on the Next engine

The demo application runs without a license key, with a stamp on the output, so you can compare Classic and Next side by side before changing anything in production.