October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
KnpSnappyBundle

How to Generate PDFs with KnpSnappyBundle in Symfony (wkhtmltopdf)

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Short answer: install knplabs/knp-snappy-bundle, install the external wkhtmltopdf executable, configure its absolute path, render your Twig view to HTML, and pass that HTML to Snappy. In a controller, return the resulting bytes with PdfResponse. KnpSnappyBundle is the Symfony integration layer; wkhtmltopdf does the actual HTML-to-PDF conversion.

What KnpSnappyBundle does

KnpSnappyBundle provides Symfony services around KnpLabs Snappy. Snappy starts the wkhtmltopdf command-line program, gives it HTML or one or more URLs, and receives PDF bytes or a file. The executable is not bundled with Composer, so every machine that runs PHP (including a worker or container) needs a compatible installation.

This approach is useful for invoices, reports, tickets and other documents whose layout already exists as HTML and CSS. It can convert a rendered Twig view, an HTML string, a URL, or an array of URLs. It is not a browser automation layer: wkhtmltopdf uses an older Qt/WebKit engine and may not implement APIs used by modern JavaScript applications.

Check compatibility before installing

  • Packagist listed KnpSnappyBundle 1.10.6 on 2026-01-07, requiring PHP 8.1 or newer and Symfony FrameworkBundle ^5.1|^6.0|^7.0|^8.0. These constraints are time-sensitive; let Composer resolve the version for your application and check the package metadata at installation time.
  • Install the wkhtmltopdf release appropriate for your operating system. The project’s downloads page identifies 0.12.6 (June 11, 2020) as its stable series; its upstream repository is archived and the status documentation describes an aging Qt/WebKit base.
  • Test a representative document using the exact binary, fonts, permissions and network environment used in production. ES6 and other modern JavaScript APIs can require polyfills, and client-side rendering can finish too late or remain incomplete.

Install the bundle and renderer

1. Add the Composer package

composer require knplabs/knp-snappy-bundle

Symfony Flex normally enables the bundle automatically. Without Flex, register it in config/bundles.php:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
KnpBundleSnappyBundleKnpSnappyBundle::class => ['all' => true],

2. Install wkhtmltopdf

Use your operating system’s package or the wkhtmltopdf project’s distribution for your platform. Then find the executable (for example, with command -v wkhtmltopdf on Unix-like systems) and verify that the PHP process can execute it. Do not assume /usr/local/bin/wkhtmltopdf exists in a container, a managed host or Windows deployment.

3. Configure an absolute path

Create config/packages/knp_snappy.yaml:

knp_snappy:
    pdf:
        enabled: true
        binary: /usr/local/bin/wkhtmltopdf
        options: []
    image:
        enabled: true
        binary: /usr/local/bin/wkhtmltoimage
        options: []

Replace both paths with locations that exist in your runtime image. The bundle also supports temporary_folder (by default PHP’s system temporary directory) and process_timeout. Set a writable temporary directory and a timeout that matches your largest legitimate document:

knp_snappy:
    pdf:
        enabled: true
        binary: '%env(WKHTMLTOPDF_BINARY)%'
        temporary_folder: '%kernel.cache_dir%/snappy'
        process_timeout: 60
        options: []

Create the temporary directory during deployment and ensure the web-server user can write to it. An environment variable keeps the executable path different between development, containers and production.

Generate a PDF from a Twig template

Controller response (no intermediate file)

Render the template first, then ask the injected Pdf service for bytes. PdfResponse sets a PDF response and download filename:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php
namespace AppController;

use KnpSnappyPdf;
use KnpBundleSnappyBundleSnappyResponsePdfResponse;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;

final class ReportController extends AbstractController
{
    #[Route('/reports/{id}.pdf', name: 'report_pdf')]
    public function pdf(Report $report, Pdf $knpSnappyPdf): PdfResponse
    {
        $html = $this->renderView('report/show.html.twig', [
            'report' => $report,
        ]);

        return new PdfResponse(
            $knpSnappyPdf->getOutputFromHtml($html),
            'report-' . $report->getId() . '.pdf'
        );
    }
}

Report is application-specific; load it with your normal controller argument resolver or repository. The route returns a PDF download. If you want inline display, use a normal Response and set Content-Disposition yourself while keeping the bytes from getOutputFromHtml().

Write a file for later delivery

$html = $this->renderView('report/show.html.twig', ['report' => $report]);
$knpSnappyPdf->generateFromHtml($html, $outputPath);

Use a path outside the public directory for private documents, then stream it through an authorization-checked controller or object storage. Ensure the destination directory exists and is writable.

Make asset URLs absolute

wkhtmltopdf runs as a separate process. Relative references such as css/report.css or images/logo.svg can fail because the process has no browser page base URL. Generate absolute, reachable URLs (or embed assets) before conversion. In production, confirm DNS, TLS certificates, authentication and firewall rules permit the renderer to reach those URLs. A document that renders in your browser can still miss fonts or images from the server process.

Generate from a URL or several pages

When the source is already published, Snappy can generate from a URL; it also accepts an array when you need multiple pages or sections:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
$knpSnappyPdf->generate(
    ['https://example.test/section-a', 'https://example.test/section-b'],
    $outputPath
);

Prefer rendering a controlled internal URL when its authentication and network access are explicit. For user-provided URLs, apply allow-lists, authentication boundaries and outbound-network controls; otherwise the renderer can be abused to request internal services.

Useful wkhtmltopdf options

Pass supported command-line options in the options map or as the second argument to Snappy methods. Keep the options that define your document in one configuration service so every export is consistent. Common categories include:

Rank #3
Sale
The Definitive Guide to symfony
  • Used Book in Good Condition
  • Page geometry: paper size, orientation, margins and zoom.
  • Headers and footers: page numbers, dates and static text.
  • Loading: JavaScript delay, quiet mode and custom cookies or headers where your deployment requires them.
  • Links and assets: local-file access and image loading. Enable only what your controlled templates need.

Option names and support vary by the installed wkhtmltopdf build. Run wkhtmltopdf --help on the production binary and validate each option with a real PDF rather than assuming a browser feature exists.

Security boundaries you must enforce

The wkhtmltopdf project explicitly warns: “Do not use wkhtmltopdf with any untrusted HTML – be sure to sanitize any user-supplied HTML/JS, otherwise it can lead to complete takeover of the server it is running on!” Treat submitted HTML, CSS and JavaScript as code, not text.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Render server-owned Twig templates with escaped variables. Do not concatenate arbitrary user HTML into them.
  • If rich text must be accepted, sanitize it with a narrowly defined HTML policy, remove scripts and event handlers, and test the sanitizer’s output.
  • Avoid broad local-file access for arbitrary input. Run the converter with the least-privileged OS account, a restricted filesystem and controlled outbound network access.
  • Protect URL-based generation against SSRF. Allow-list hosts, block private address ranges and do not pass a user URL straight to wkhtmltopdf.
  • Keep generated files in non-public storage and apply authorization, retention and deletion rules.

JavaScript, CSS and font limitations

wkhtmltopdf’s WebKit engine predates many current browser APIs. ES6 features may need polyfills, and a Vue, React or Angular screen that fills itself after hydration can become blank or partly rendered. Prefer server-rendered Twig for deterministic output. If JavaScript is unavoidable, use a controlled delay, avoid unsupported APIs, and include a test fixture that checks charts, web fonts, images, page breaks and right-to-left text.

Do not use a delay as a substitute for a failed asset: a blocked stylesheet or inaccessible font will never load. Log the generated command’s stderr in a controlled way (without exposing secrets) and compare a development PDF with a production PDF.

Troubleshooting checklist

“The system cannot find the file specified”

The configured binary path is wrong or unavailable to the PHP user. Run the path as that user, check execute permissions and set the environment-specific path in knp_snappy.yaml.

“Permission denied” or temporary-file errors

The process cannot execute wkhtmltopdf or write its temporary directory. Fix ownership and permissions, create the configured directory during deployment, and verify available disk space.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Blank PDF or missing CSS/images

Inspect every URL from the renderer’s network position. Convert relative links to absolute URLs, make private assets accessible with controlled credentials, check TLS and DNS, and ensure the required resource types are not blocked by the environment.

Modern layout or JavaScript is broken

Assume an engine-compatibility problem first. Move essential layout and data to server-rendered HTML, add polyfills only where safe, and test against the exact wkhtmltopdf build. If the document depends on a current browser engine, reassess the renderer rather than adding arbitrary delays.

Request times out

Find the slow URL, asset or script, then set an appropriate process_timeout and per-document loading strategy. Do not set an unlimited timeout: a stuck renderer can exhaust PHP workers. Queue large exports and return a job status instead of holding a web request open.

Output differs between machines

Pin the OS image, wkhtmltopdf build, fonts, locale and timezone used for exports. Differences in installed fonts and WebKit patches commonly change line wrapping and pagination.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability and operations

  • Rendering is a separate process, so account for process startup, HTML size, image downloads and JavaScript execution when setting web-server and PHP timeouts.
  • For small reports, a synchronous PdfResponse is simple. For large or bursty workloads, dispatch a Messenger job, save the file, and notify the client when it is ready.
  • Cache stable PDFs using a versioned report identifier and input hash. Invalidate when template, data, locale or assets change.
  • Record duration, exit status, output size and a correlation ID. Avoid logging full HTML, cookies or authorization headers.
  • Use a health check that runs the binary against a tiny known template after deployment; this catches missing executables, fonts and permissions before users request invoices.

Or skip the browser setup

If your requirement is simply “give me a clean PDF or screenshot of a URL,” ScreenshotNeo is an alternative API. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; failed bot checks, blank pages, timeouts, failed loads and cache hits are not billed. Its MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

For a direct PDF request, see the ScreenshotNeo API documentation. The same endpoint can return PNG, JPEG, WebP or PDF:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo’s Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.

Choosing this bundle responsibly

KnpSnappyBundle is a practical fit when your templates are server-rendered, your deployment can install and isolate an external executable, and wkhtmltopdf’s HTML/CSS behavior matches your documents. Reconsider it when you require modern browser APIs, untrusted arbitrary HTML, strict renderer maintenance guarantees or a fully managed capture service. Compare compatibility, operating-system support, isolation requirements, PDF features and renderer maintenance with any alternative, and base the decision on a production-like document rather than a minimal demo.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I inject the Snappy service instead of fetching it from the container?

Yes. Type-hint KnpSnappyPdf in a controller or service; Symfony’s container supplies the configured PDF client.

Does KnpSnappyBundle install wkhtmltopdf for me?

No. Composer installs the Symfony bundle, while wkhtmltopdf remains an operating-system executable that you install and configure separately.

Can one request combine several URLs?

Yes. Snappy’s generation methods accept an array of URLs, subject to network access, authentication and the renderer’s ability to load each page.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.