wkgtk-html2pdf c++ API manual


rev V0.0.13.20260212_01

Index

  1. INTRODUCTION
  2. COMMAND LINE INTERFACE:
  3. OPTIMISING HTML:
  4. LINKS/ANCHORS:
  5. ARTEFACTS:
  6. PAGE DESIGN HELPER:
  7. HINTS AND TIPS:
  1. C++ API:

1. Introduction

wkgtk-html2pdf is a powerful and easy-to-use API for converting HTML content into high-quality PDF documents using WebKitGTK. Developed as a modern alternative to legacy tools like wkhtmltopdf—which has been archived since 2023—this project fills the gap for reliable, up-to-date HTML-to-PDF conversion. It provides a clean, intuitive C++ API that simplifies HTML generation by eliminating the need for string literals and explicit closing tags, making it ideal for embedding in applications. The tool supports advanced features such as internal anchors, links, and nested sidebar indexing, enabling the creation of structured, navigable PDFs. A simple command-line interface is also available for quick, one-off conversions. With its focus on maintainability and modern development practices, wkgtk-html2pdf is designed to be a reliable choice for developers seeking a dependable solution for PDF generation.

This project is entirely inspired by wkhtmltopdf as when we were searching for a replacement we simply could not find one, and even the paid for options seemed overly complex where they needn't be and severely lacking where they should. We have tried to iron out some of the issues we have encountered along the way and have produced this manual to assist with those unavoidable issues that must be worked around. We hope that you find this project useful and we would be very much appreciative of any contribution, be that funding, documentation, testing, or design.

wkgtk-html2pdf includes a set of built-in, pre-configured CSS templates for all standard ISO and US paper sizes, ensuring compatibility and consistency across different regions and use cases. These templates are designed to prevent the generation of extraneous blank pages by precisely defining page dimensions, margins, and layout constraints using CSS custom properties.

Each template uses a clean, modular structure with variables for page width, height, and margin, allowing for easy customization while maintaining reliable output. A lightweight JavaScript utility is included to monitor content overflow in real time—when content exceeds the available space, the subpage border turns red; when it fits perfectly, the border turns green. This visual feedback helps you quickly identify and resolve layout issues before conversion.

The templates also include print-specific CSS rules that ensure clean, artefact-free output when the HTML is rendered to PDF, while maintaining visual guides during development for easier debugging and refinement.

In wkgtk-html2pdf we have endeavoured to create a system that does not require you to learn additional languages; all you should need is a reasonable understanding of HTML.

1.1 Reading this manual

This manual is a self fulfilling prophecy as it is developed entirely using wkgtk-html2pdf so the layout the code that is used to write it is in itself a tutorial. If you are uncertain about how something is done then is worth reviewing the HTML and CSS used to generate it.

1.2 Architectural Philosophy: Built for Stability

Unlike many wrapper libraries that expose internal dependencies to the host application, wkgtk-html2pdf is engineered with a strict Binary Interface (ABI). We utilize the Pimpl (Pointer to Implementation) idiom throughout the C++ API to create a "firewall" between the library's internal logic and your application. This tedious but essential design choice provides several critical benefits:

2. Command line interface (CLI)

The CLI is the simplest way to get started with wkgtk-html2pdf. It allows you to convert HTML files into PDFs with minimal setup.

2.1 Basic Usage

To generate a PDF using the default settings use the following command:

html2pdf -i input.html -o output.pdf

2.2 Command line options

The following options are available for the cli.

Option Description
-h, --help Display the help message with all available options.
-v, --verbose Set the log level (1-7), with higher values providing more detailed output. Logs are written to the system journal.
-i, --infile Specify the source HTML file to convert.
-o, --outfile Specify the output PDF file name.
-O, --orientation Set page orientation: portrait or landscape.
-s, --size Set the page size (Default A4)
- ISO (A): A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10
- ISO (B): B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10
- ISO (C): C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10
- US: Letter, Legal, Tabloid
- ANSI: ANSIA, ANSIB, ANSIC, ANSID, ANSIE
- Architectural: ArchA, ArchB, ArchC, ArchD, ArchE
- Other: SRA0, SRA1, SRA2, SRA3, SRA4
--index Create anchor points for indexing: classic or enhanced for nested sidebar indexing.
-r --relative-uri look for resources such as images in, or relative to, the current working folder.

3. Optimising HTML

To generate a clean, professional PDF, you must optimize your HTML to ensure it aligns with the desired page size and layout. The output is entirely governed by the CSS and HTML structure, so the quality of the final PDF depends on how well your content is designed.

3.1 Key Principles

3.1.1 Use the correct stylesheet

  1. Each stylesheet is named according to the page size and orientation it supports (e.g., A4-portrait.css, ANSIA-landscape.css).
  2. Link to the appropriate stylesheet in your HTML:
Example:
<link rel="stylesheet" href="/usr/share/wk2gtkpdf/A4-portrait.css">
Applying the Style Sheet for A4 portrait.

3.1.2 Use the correct classes

  1. Use the .page class to define the overall page
  2. Use the .subpage class to define content areas.
Example:
<div class="page">
    <div class="subpage">
        <!-- Your page content here -->
    </div>
</div>
Initialising page boundaries

3.1.3 Monitor the overflow

  1. Include the JavaScript utility to monitor content overflow.
  2. If overflow is detected the margin turns red.

This script provides real-time feedback, helping you identify and fix layout issues before conversion.

<script src="/usr/share/wk2gtkpdf/overflow-monitor.js><script>
Declaring the JavaScript to monitor the overflow.

3.1.4 Avoid common issues

By designing your HTML and CSS carefully, you have full control over the final PDF output. Avoid common issues: Mismatched stylesheets, incorrect classes, or content overflow can lead to blank pages, cut-off content, or incorrect scaling.

The overflow detection script helps you identify and fix layout issues before conversion.

3.1.5 Best Practices

  1. Always test the layout - Use the overflow detection script to ensure content fits within the page. Adjust the CSS or content as needed to avoid overflow.
  2. Use the correct stylesheet - Ensure the stylesheet matches the CLI arguments (page size and orientation).
  3. Keep it consistent - Use the same page size and orientation in both the CSS and CLI arguments.

3.2 Quick start - A4 Portrait Layout

Below is a minimal, single-page example utilizing the built-in overflow monitor and missing-font detector.

Example:
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="/usr/share/wk2gtkpdf/A4-portrait.css">
</head>
<body>
    <div class="page">
        <div class="subpage">
            <h1>My Document</h1>
            <p>This content will be rendered in A4 portrait format.</p>
        </div>
    </div>
</body>
<script src="/usr/share/wk2gtkpdf/overflow-monitor.js><script>
</html>
Minimal single page example.

Each declaration of a .page and .subpage container will create a new page. Blank pages can also be inserted by declaring a .page and .subpage container.

4. Anchors

wkgtk-html2pdf offers two indexing modes to generate the PDF sidebar navigation: Classic and Enhanced.

4.1 Classic mode

In Classic mode, the engine automatically scrapes all internal anchors (any <a> tag where the href starts with #) and includes them in the PDF index. This is ideal for simple documents where every link is a significant navigation point.

Example:
<!-- Automatically indexed in Classic Mode -->
<li><a href="#reference">Reference</a></li>
<p><a href="#section1">Section 1</a></p>
<div><a href="#appendix">Appendix</a></div>
All these anchors are valid.

4.2 Enhanced mode

Enhanced mode (--index enhanced) is a professional-grade feature that allows for selective indexing. Only elements explicitly marked with the index-item class,class will appear in the PDF sidebar. This prevents "index noise" in documents with many internal cross-references.

Example:
<!-- This will be included -->
<li class="index-item">
    <a href="#reference">
        <span>Reference</span>
        <span>A1</span>
    </a>
</li>

<!-- This will be ignored -->
<p><a href="#section1">Section 1</a></p>

<!-- This will be included (container type doesn't matter) -->
<div class="index-item">
    <a href="#appendix">Appendix</a>
</div>
Enhanced anchor declarations.

In this example only the first and third elements will be included in the index. While this feature may not be essential for most users, it could be useful in specific scenarios where you want to:

  1. Exclude certain internal links from the index.
  2. Create a more structured or semantic index.

The benefits of enhanced mode will become more clear after you read the section on sidebar indexing below.

Clickable areas marked in grey.

Save for the styling the difference is

Enhanced:
<li class="index-item"> <a href="#ref"> <span> Enhanced mode </span> <span> 4.1 </span> </a> </li>
A typical enhanced mode link.
Classic:
<li> <a href="#ref"> <span> Enhanced mode </span> <span> 4.1 </span> </a> </li>
A typical demo_classic mode link.

As you can see from the code, theoretically the link should work across the entire line, even in classic mode but it doesn't (even in HTML). Ordinarily when you convert your link to a you lose right right hand side part of the anchor unless you enable enhanced mode

Most users familiar with PDF technical manuals rely heavily on the sidebar index (bookmarks). This navigation tree remains on-screen at all times, making it more practical than a traditional printed index page. Regardless of whether you choose Classic or Enhanced mode, wkgtk-html2pdf automatically builds a nested, hierarchical sidebar by analyzing your HTML structure.

4.3.1 Indexing Criteria

For an item to appear in the PDF sidebar index, it must satisfy two conditions:

  1. Unique Linkage - The source anchor must reference a target with a unique ID
    (e.g. <a href=#mylink>)
  2. Numbered Hierarchy - The target element must contain a number. To create nested levels
    (e.g., Section 1.1 inside Section 1.0), use a period separator.
Example:
<a href=#setup_guide>Go to Setup</a>
<h2 id=setup_guide>1.1 System Setup</h2>
Creating an index item.

The engine will parse "1.1" and automatically nest this bookmark under "1.0" in the PDF sidebar.

4.3.2 Enhanced vs. Classic: The Clickable Area

Aside from selective filtering, Enhanced Mode offers a significant UX advantage regarding the "Clickable Area."

In standard HTML, an anchor often wraps only the text, leaving the rest of the line (such as the page number or dot leaders) unclickable. Enhanced Mode expands the interactive hit-box to include the entire .index-item container. This ensures that in the final PDF, the user can click anywhere on the index line—not just the text—to jump to the section.

Below is a live example which may or may not appear in the index depending on whether you create the PDF using enhanced index mode or classic.

Take me to your linker

1.1 I am here

A live example in classic indexing mode.
Sample pdf with sidebar index.

The link has been explicitly disabled when the manual is compiled with indexing in enhanced mode to further demonstrate why this might be useful. You will note that if you compile this manual in classic mode you will actually see the link in the sidebar nested in section 1. Were we not demonstrating how this works that behaviour would be undesirable but we can disable it in advanced mode without causing problems for the rest of the document.

If you wanted to enable the link in enhanced mode then it is as simple as wrapping the anchor in an element with the a class of "index-item".

<span class="index-item"><a href="#enhanced-anchor" >Take me to your linker</a></span>;
<p id="enhanced-anchor">4.3.1 Enhanced indexing anchor demo</p>
Enabling the link in enhanced indexing mode.

Enhanced mode links work in both classic and enhanced mode.

Take me to your linker

4.3.1 Enhanced indexing anchor demo

A live example in enhanced indexing mode.

The above link will appear in the index. This time you will note that we have explicitly numbered the link 4.3.1 so that it will appear nested in section 4.3 within the index.

4.4 Index page

If you do have an index page then attaching it to the sidebar is as simple as declaring toc within the page element.

Example:
<div class="page toc">
    <div class="subpage">
        <!-- Your page content here -->
    </div>
</div>
A page declared as the commencement of the table of contents.

The table of contents should be declared exactly once per document.

NOTE:If it is declared more than once the the first declaration that wkgtk-html2pdf finds will be used and the rest will be ignored.

When you declare a Table of Contents/Index page it will be attached to the top level "Contents" bookmark within the index.

5. Artefacts

5.1 Images

If your document contains images then you have a number of options. The first is if they are served from a URL then they will just work without straight out of the box.

A randomised image from the internet.

As this is a semi interactive manual if you are viewing this in html you should see a random image generated. This image will be embedded in the PDF upon generation.

Both static and relative paths also work however if you are using relative paths then the images must be contained within the working directory and you must use the -r flag on the cli (no argument need be specified). Full paths are also supported.

An image from a static path.

Base64 encoded images also work work should you wish to embed them directly in your HTML.

5.2 Fonts

Special attention is required when working with fonts, as missing fonts can cause overflow and unexpected results; especially when the fallback font differs significantly from the intended font.

Within our suite we have included a JavaScript snippet that if enabled should detect missing fonts and warn you before you generate your PDF. As long as wkgtk-html2pdf can see the font it should render the page correctly.

6. Page design helper

When converting or generating HTML that works seamlessly as a PDF there are several issues that may lead to unexpected results. While not an exhaustive list the following are most common:

  1. Unexpected extra pages - It is not unusual for developers to become extremely frustrated at the fact that they have an extra blank page at the end of their document even though they have done everything right.
  2. Overflow - Content is often missing or going off the page.

In an attempt to combat these problems that plague HTML to PDF conversion we have incorporated a small JavaScript helper that works alongside our CSS stylesheets to try help combat these problems.

6.1 CSS Style sheets

When you include the appropriate template for your desired page size and declare a .page and .subpage <div> element. You will note that you now have something on screen that represents the page size of the PDF you are developing. This will include a margin outlined in blue.

All of the page templates are located in

/usr/share/wk2gtkpdf/templates

Default path of the wkgtk-html2pdf stylesheets.

If you wish to change one of the page margins then it is simply a matter of editing the appropriate stylesheet by changing --page-margin value as needed.

NOTE: The margin is measured in millimetres(mm).

:root {
    --page-width: 210;
    --page-height: 297;
    --page-margin: 8;
}
The page margin set in the CSS.

These stylesheets contain calculations that ensure there are no extra blank pages when the PDF is generated. They also provide you with a visual representation of a page including its margins.

For Section 6 (Layout & Consistency), you can frame the new GTK4 viewer as the "Gold Standard" for accuracy, while addressing the reality of web rendering drift. Here is a draft for the amendment that fits the "single source of truth" philosophy: 6.2 The GTK4 Reference & Browser Drift The development of the GTK4-based Desktop Viewer now provides the ultimate baseline for document accuracy. Because it uses the same underlying C++ engine as the PDF generator, it offers a true "What You See Is What You Get" (WYSIWYG) experience, free from the font-metric rounding errors common in web browsers. 6.2.1 Safe Layout Practices (Slug Lines) While the applyTextShave script compensates for rendering differences in modern browsers (Chrome, Safari, Firefox), certain environments—specifically Falcon, Qt-based browsers, or systems with missing fonts—can still experience significant layout drift. To maintain professional integrity in these "obscure" environments: The Safety Slug: It is strongly advised to leave a "safety slug" or a small vertical margin at the bottom of each .subpage. Purpose: This provides a buffer for font substitution or aggressive kerning drift, ensuring that a critical line of text isn't "shaved" off the bottom of the visible page. Recommendation: Aim for a 3mm to 5mm clear zone at the page footer. If a manual passes the GTK4 validation but shows text entering this zone, it should be considered "at risk" for web-based overflow.
A blank A6 page with margins outlined.

As long as you keep your content within the subpage element it should stay within the margins and on the provision that the font is accessible and given the appropriate arguments it should render identically with the command line interface.

6.2 JavaScript helper utility

As aluded to several times throughout this manual wk2gtk-html2pdf includes a helper utility to aid with design. It is located in the same folder as the CSS templates and can be used to identify problems before trying to generate a PDF.

To use the utility you need to declare it:

<script src=""/usr/share/wk2gtkpdf/overflow-monitor.js"><script>

Once declared it will automatically monitor changes in the background and warn of any detected Issues in a panel which will appear towards the bottom left corner of the your preview.

Notification when the content goes outside of the page margin

In addition to the detection of overflow it should also be capable of detecting missing fonts. This is to be considered advisory and if there are rendering issues the first thing that should be checked is the system wide availability of fonts.

NOTE: Font detection has been checked in most cases however it should be noted that due the manner in which detection is achieved is should not be considered reliable in 100 percent of cases.

TO SORT OUT!!! Engine Family Principal Browser Common "Wrappers" or Forks Blink (Chromium) Chrome, Edge Falkon, Brave, Opera, Vivaldi, Arc WebCore (WebKit) Safari WebKitGTK (your PDF engine), Epiphany/GNOME Web Gecko Firefox Waterfox, Mullvad Browser, Librewolf "While modern browsers are largely interoperable, authors should be aware of the Engine Divergence. Chrome, Edge, and Opera (Blink) will render text with slightly different glyph widths than Safari and our GTK4 Viewer (WebKit). Firefox (Gecko) remains the strict outlier for CSS parsing. Design work should ideally be performed in the GTK4 Development Tool to ensure the 'shaved' metrics are validated against the actual C++ PDF output." Update documentation for new viewer. and advise on issues with relying on broswers also suggest workaround to leave a bit at the bottom so that fit is guaranteed.

Notification when a missing font is detected

7. Hints and Tips

7.1 Page Numbering

You will note that the pages within this document are all numbered. That is an automatic feature that we do using CSS and it is done utilising CSS' built in counter function:

div.subpage:after {
     content: " Page - " counter(page);
     position: absolute;
     bottom: 0px;
     right: 0px;
     z-index: 999;
     padding: 2px 8px;
     border-right: 2px solid #23b8e7;
     font-size: 12px;
 }
 
An automated page counter positioned towards the bottom right of the subpage

Apart from some basic styling this is relatively simple as all that is needed is

content: " Page - " counter(page);
Page numbering with a prefix

or if you just want a number

content: counter(page);
Basic page numbering

You will note however that our counter does not start on page 1 (in fact it starts on the 3rd page). To achieve this we need to allow the counter to count up, but hide it on the pages that we do not want it to be visible on, then we need to reset it and make it visible. It is a bit of a hack, but it is easier than keeping track of page numbers manually.

/* Hide the counter on pages 1 and 2 */
div.page:first-child div.subpage::after,
div.page:nth-child(2) div.subpage::after {
    display: none;
}
/* Reset the counter on the 3rd page */
div.page:nth-child(3) {
    counter-reset: page;
}
/* Increment the counter every time a new page is encountered */
div.page:not(:first-child) {
    counter-increment: page;
}
Restart the counter on page 3

We are all used to seeing linke underlined on web pages but for some it can seem an unnecessary distraction when transcribed to a PDF. Albeit subjective (as all design is) personally I like to get rid of the underline but keep the blue colour just to hint to the user that it is clickable.

To change this or any formatting specifically for pdf generation you use the @media print directive in your CSS.

@media print {
    a {
        text-decoration-line: none !important;
    }
}
Remove the underline from links for PDF

7.3 Remove the visible page margin

Chances are that if you have gone to the trouble of writing a lengthy document in HTML then you may wish to utilise it in HTML format. The problem is that you have a big blue margin around the outside of your page. You may be tempted to set the border to none however that would be ill advised as it could change the formatting. The best thing that you can do to ensure nothing changes is to leave it where it is and just make it white.

.subpage {
    border: solid white !important;
}
Hide the margin guide

7.4 Development environment setup

Depending on what we are doing we use both of these setups (sometimes even both at once), but as long as you have something to preview and something to write code on you shouldn't run into difficulties.

7.4.1 Pulsar-edit

Without doubt our favorite ide for developing anything HTML is Pulsar-edit. Along with the atom-preview-html plugin you can configure it to perform real time updates as you type, it has plugins for code snippets and when utilised along with our JavaScript plugin can be a real time saver once you get used to it.

'.text.html.basic':
    'Page and Subpage':
        'prefix': 'hpage'
        'command': 'insert-page-subpage'
        'body': '<div class="page">\n <div class="subpage">\n </div>\n</div>'
        'description': 'Insert page and subpage container'
    'Code box':
        'prefix': 'bcode'
        'command': 'insert-codebox'
        'body': '<div class="code-container">\n \t<div class="code-container-sub">\n \t<pre><code>\n </code></pre>\n \t</div>\n</div>'
        'description': 'Insert code snippet container'
Our pulsar snippets for inserting the code and page entries to produce this manual

We believe that VS Code is another solid alternative that works similarly however we haven't used it ourselves.

7.4.2 Vim and a browser

If you love vim then you probably don't need us to tell you how to set up your environment but in testing we have found that previewing the output with Falkon browser results in the almost real time updates on save without need to manually refresh the page refresh. While probably not the world's greatest browser for daily internet use we have found it the best solution for live previewing while using your favourite text editor (be that vim, nano, or something less hardcore) to design your pages.

8. C++ API

The wkgtk-html2pdf library provides a professional-grade C++ interface designed for high-performance document automation. Starting with Version 1.0.0, the API utilizes the Pimpl (Pointer to Implementation) idiom, ensuring a stable Application Binary Interface (ABI). This allows the internal rendering engine to be updated without requiring the host application to be recompiled.

8.1 Key Concepts

The wkgtk-html2pdf C++ API is designed for professional document automation where long-term binary compatibility is a requirement. To achieve this, the library adheres to two core principles:

8.1.1 The Binary Wall (Pimpl)

Every public-facing class such as PDFprinter and html_tree utilises the Pointer to Implementation (Pimpl) idiom. The header files contain no private members from third-party libraries (WebKit, PoDoFo, or GLib).

8.1.2 Thread Safety & Initialization

The rendering engine utilizes a Singleton pattern for GTK initialization.

icGTK::init():
Initialsing GTK.

This must be called once at the start of your application. It manages the heavy WebKit infrastructure within a dedicated thread, ensuring your main application loop remains responsive.

8.2 The html_tree Class (DOM Construction)

The html_tree class allows for programmatic construction of well-formed HTML without manual string concatenation. cpp

#include <wk2gtkpdf/ichtmltopdf++.h>

// 1. Create the Root
phtml::html_tree dom("html");

// 2. Nest Elements
phtml::html_tree *body = dom.new_node("body");
phtml::html_tree *h1   = body->new_node("h1");

// 3. Set Content (ABI-safe strings)
h1->set_node_content("Professional PDF Report");

// 4. Extract HTML string
phtml::process_nodes(&dom);
const char *html = dom.get_html();

// 5. Cleanup
phtml::PDF_FreeHTML(html);
Minimal example using built in DOM constructor.

8.3 The PDFprinter Class (Rendering)

The PDFprinter class manages the conversion of HTML strings into PDF documents or raw binary data.

#include <wk2gtkpdf/ichtmltopdf++.h>

// Initialize the Global GTK Loop (Call once)
icGTK::init();

phtml::PDFprinter pdf;

// Set input HTML and Output filename
pdf.set_param(html, "report.pdf");

// Set Layout parameters
pdf.layout("A4", "portrait");

// Execute Rendering
pdf.make_pdf();

8.4 Working with BLOBs

For advanced workflows (e.g., post-processing with ImageMagick), the library can return the PDF as a raw memory buffer.

pdf.set_param(html); // No filename provided = BLOB mode
     pdf.make_pdf();

     // Retrieve Binary Data
     phtml::PDF_Blob binDat = pdf.get_blob();

     // ... process binDat.data (size: binDat.size) ...

     // Explicitly free the library-allocated memory
     phtml::PDF_FreeBlob(binDat);

8.5 Variadic Helpers

To facilitate dynamic content generation, the API includes printf-style helpers that handle internal buffering automatically.

new_node_f(const char *format, ...)
set_node_content_f(const char *format, ...)

8.6 Indexing Configuration

The wkgtk-html2pdf engine provides three distinct modes for generating PDF sidebar bookmarks (the document outline). This is controlled via the phtml::index_mode enumeration.

8.6.1 The index_mode Enum

When calling the rendering methods, you must pass one of the following flags:

Constant Description
index_mode::OFF Default. No sidebar bookmarks are generated.
iindex_mode::CLASSIC Scrapes all <a> tags with internal # anchors.See 4.1 Classic mode
index_mode::ENHANCED Only indexes elements explicitly marked with the index-item class. See 4.2 Enhanced mode

8.6.2 API Implementation

To enable indexing within your C++ application, pass the mode as the third argument to the parameter setup function.


#include <wk2gtkpdf/ichtmltopdf++.h>

// 1. Initialise the printer
phtml::PDFprinter pdf("file:///path/to/resources/");

// 2. Set parameters with Indexing Mode
// Signature: set_param_from_file(const char* infile, const char* outfile, index_mode mode)
phtml::index_mode myMode = phtml::index_mode::ENHANCED;

pdf.set_param_from_file("input.html", "output.pdf", myMode);

// 3. Configure layout and render
pdf.layout("A4", "portrait");
pdf.make_pdf();
 

8.6.3 Strategic Usage

8.7 Choosing Your Engine: GTK3 vs. GTK4 Because a single Linux process cannot safely load both libgtk-3 and libgtk-4 simultaneously, wkgtk-html2pdf is distributed in two distinct builds. Selecting the correct version depends entirely on your application's environment. 1. The Headless / CLI Rule If you are building a standalone server-side tool or using the CLI, always prefer the GTK4 / WebKit6 version. It utilizes a more modern rendering engine, better CSS compliance, and more efficient memory management. 2. The Integration Rule (Desktop Apps) If you are embedding the library into an existing GUI application, you must link against the version that matches your toolkit: GTK3 Applications: Use libwk2gtkpdf-4. This links against webkit2gtk-4.1 (GTK3). Linker flag: $(pkg-config --libs wk2gtkpdf-4) GTK4 Applications: Use libwk2gtkpdf-6. This links against webkitgtk-6.0 (GTK4). Linker flag: $(pkg-config --libs wk2gtkpdf-6) 3. Why the Linker Matters Attempting to link a GTK3 application against the GTK4 version of the library will result in a Segmentaton Fault or a Critical Gdk-Error at startup. This is not a limitation of the library, but a fundamental restriction of the GTK display backend. 4. The "Chameleon" PC File To make development easier, we provide a master pkg-config file wk2gtkpdf.pc. By default, this symlinks to the GTK4 (v6) version. If your build environment requires GTK3, ensure you explicitly point your build system to wk2gtkpdf-4.pc. 8.8 Troubleshooting Linker Conflicts The most common issue when integrating wkgtk-html2pdf into a desktop application is a "Toolkit Mismatch." Because GTK3 and GTK4 cannot coexist in the same memory space, linking the wrong version will cause an immediate failure. How to Identify a Mismatch If your application compiles but crashes immediately upon calling icGTK::init(), check your system logs (journalctl -xe). You will likely see one of the following: Critical Error: Gtk-ERROR **: GTK+ 3.x symbols detected. Using GTK+ 2.x and GTK+ 3.x in the same process is not supported. (Or a similar error regarding GTK4). Segmentaton Fault: An immediate SIGSEGV during gtk_init or webkit_web_view_new. Symbol Lookup Error: undefined symbol: gtk_widget_show_all (which exists in GTK3 but was removed in GTK4). The "ldd" Sanity Check If you are unsure which version your binary is actually pulling in, use the ldd command on your compiled executable: bash # Check for GTK3 (WebKit 4.1) ldd your_app | grep libwebkit2gtk-4.1 # Check for GTK4 (WebKit 6.0) ldd your_app | grep libwebkitgtk-6.0 Use code with caution. If you see both appearing in the list, your build system is misconfigured and linking against two different versions of the library. Correcting the Build Ensure your Makefile or CMakeLists.txt is calling the versioned .pc file that matches your app: For GTK3 apps: pkg-config --libs wk2gtkpdf-4 For GTK4 apps: pkg-config --libs wk2gtkpdf-6 Minimum OS: Debian 12 (Bookworm) or Ubuntu 22.04 (Jammy Jellyfish). Dependencies: libwebkit2gtk-4.1 (for v4) or libwebkitgtk-6.0 (for v6). FUTURE PLANS Why this is the only choice right now skia and wpe are our favoured solution cairo support removed from wpe thwarted our efforts to develop an self contained apps Why running xvfb as a daemon is better than starting an instance with the application (each instance will hog the DISPLAY) We tried weston before xvfb and it woud not work to generate pdf's Whateer we use the api should remain the same because of pimpl