ScreenshotNeo

BlogHow-to

PDFCrowd PHP API Example for Converting HTML to PDF in WordPress

Generate a WordPress PDF download with PDFCrowd’s PHP client. Choose the right input method, secure the handler, and return valid PDF bytes.

By the ScreenshotNeo team4 October 202610 min read

Direct answer: For WordPress content you render on the server, install PDFCrowd’s PHP client with Composer, build the authorized page or report as an HTML string, and pass it to HtmlToPdfClient::convertString(). Return the resulting bytes with Content-Type: application/pdf. Use PDFCrowd’s URL method only when its conversion servers can reach the page and its assets. Keep the API credentials server-side, validate the request nonce, and separately authorize access to the content.

This is an integration pattern assembled from PDFCrowd’s documented PHP methods and WordPress conventions. It is an illustrative skeleton, not a vendor-published or tested plugin. Adapt the action, capability checks, content lookup, template, error handling, and configuration to your site.

1. Choose the input method

Input PHP method Use it when Watch for
HTML string convertString() or convertStringToFile() WordPress has already assembled the document HTML, including authorized dynamic data. Include the styles and assets needed by the document. Relative asset URLs need a valid base or should be changed to accessible absolute URLs.
URL convertUrl() or convertUrlToFile() The page is publicly reachable from PDFCrowd’s conversion servers. A page that loads in your logged-in browser may still be inaccessible to the remote converter. Private pages, local hostnames, and session-only resources generally need another input route.
HTML file or archive convertFileToFile() You have a local HTML file or need to package local assets with the HTML. For an archive containing multiple HTML files, configure which file is the main document.

For a WordPress page assembled from post data, a string is usually the most direct approach. If you instead need to render a particular URL, confirm that the converter can fetch both the page and every required stylesheet, image, and font. PDFCrowd documents its PHP methods and options in the PHP API guide.

2. Install and configure the PHP client

From the project directory where Composer dependencies are managed, install the package:

composer require pdfcrowd/pdfcrowd

Load Composer’s autoloader in the site-specific plugin or bootstrap that handles the request. Keep the PDFCrowd username and API key in private server configuration, such as environment-backed configuration, and never place them in a form, JavaScript, or source repository.

The examples below use placeholders for the private configuration values. Replace them with the configuration mechanism used by the site. Do not accept credentials from request parameters.

3. Add a WordPress download handler

A site-specific plugin can register an authenticated admin-post.php action. A form submits to that action, WordPress verifies the nonce, the handler checks permission to access the requested document, and then it returns the PDF bytes.

<?php
// In a site-specific plugin. Composer must be installed and its autoloader loaded.
add_action('admin_post_my_site_pdf', 'my_site_pdf_handler');

function my_site_pdf_handler() {
    check_admin_referer('my_site_pdf');

    // This is only a basic capability example. Also authorize access to the
    // specific post, report, or record requested by this user.
    if (! current_user_can('read')) {
        wp_die('You are not allowed to generate this PDF.', '', ['response' => 403]);
    }

    // Build from authorized WordPress data and an escaped template.
    // Keep required CSS inline or use asset URLs reachable by the converter.
    $title = 'Example report';
    $html = '<!doctype html>'
        . '<html><head><meta charset="utf-8">'
        . '<style>body { font-family: sans-serif; }</style>'
        . '</head><body><h1>'
        . esc_html($title)
        . '</h1><p>Generated from WordPress.</p></body></html>';

    try {
        $client = new \\Pdfcrowd\\HtmlToPdfClient(
            PDFCrowd_USERNAME_FROM_PRIVATE_CONFIG,
            PDFCrowd_API_KEY_FROM_PRIVATE_CONFIG
        );
        $pdf = $client->convertString($html);

        // Clear output buffers so notices/theme output cannot corrupt the PDF.
        while (ob_get_level()) {
            ob_end_clean();
        }
        nocache_headers();
        header('Content-Type: application/pdf');
        header('Content-Disposition: attachment; filename="report.pdf"');
        header('Content-Length: ' . strlen($pdf));
        echo $pdf;
        exit;
    } catch (\\Pdfcrowd\\Error $error) {
        error_log('PDFCrowd conversion failed: ' . $error);
        wp_die('PDF generation failed. Please try again later.', '', ['response' => 502]);
    }
}

The constant-like credential names above are placeholders, not defined PHP constants. Replace them with values read from private configuration. If your project uses a namespace or Composer dependency injection, adjust the imports and client construction accordingly.

Submit a form to the handler

Render this form only where the user is entitled to request the document. Add the nonce field and point to the authenticated action:

<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
    <input type="hidden" name="action" value="my_site_pdf">
    <?php wp_nonce_field('my_site_pdf'); ?>
    <button type="submit">Download PDF</button>
</form>

WordPress nonces help verify request intent, but they do not prove that a user may access a particular record. WordPress explicitly says, “Nonces should never be relied on for authentication, authorization, or access control.” Check the user’s capability and the specific object’s access rules on every request. See the WordPress nonce guidance.

4. Add page options and document styling

Set conversion options on the client before calling a conversion method. The PHP guide documents options including page size, margins, custom CSS, and waiting for a page element. Choose only the options the document needs, and verify the accepted values and signatures in the current PDFCrowd PHP documentation.

$client = new \\Pdfcrowd\\HtmlToPdfClient($username, $apiKey);
$client->setPageSize('A4');
$client->setPageMargins('10mm', '10mm', '12mm', '10mm');
$client->setCustomCss('body { font-family: sans-serif; }');
$pdf = $client->convertString($html);

The snippet illustrates where options fit; confirm method argument formats against the client version installed in your project. For content produced by JavaScript, configure an appropriate readiness condition, such as waiting for a selector, so conversion does not start before the needed content exists. If a selector is not reliably present, prefer rendering the required content into the HTML before conversion.

Styles, images, and relative URLs

  • For an HTML string, include critical print styles in a <style> element or reference a stylesheet the converter can access.
  • Use absolute asset URLs when the conversion server must fetch remote images, fonts, or stylesheets.
  • If assets are local or private, use a file/archive input that packages the HTML and assets, or otherwise arrange accessible resources.
  • For URL conversion, the source page and its required resources must be reachable from PDFCrowd’s servers. Browser cookies or local network access on your WordPress host do not automatically transfer to the conversion service.

5. Return bytes or write the PDF to a file

convertString() returns PDF bytes in memory, which suits a modest on-demand download. The corresponding convertStringToFile() method writes output to a file and is useful when the application needs a saved artifact or wants to avoid keeping the complete result in a PHP variable. URL and file/archive inputs have corresponding conversion methods. Choose the method that fits your storage, response, and memory needs.

When returning bytes, send a valid PDF response:

  • Content-Type: application/pdf tells the browser the response format.
  • Content-Disposition: attachment; filename="report.pdf" asks the browser to download it with a useful name. Use inline if the intended behavior is browser display.
  • Send cache headers appropriate to the document’s privacy. For user-specific or sensitive reports, prevent shared caching.
  • Ensure no PHP warning, whitespace, theme markup, or debugging output precedes the PDF bytes.

6. Errors, security, and operational handling

The client throws Pdfcrowd\\Error for conversion or validation errors. Catch it at the request boundary, log useful server-side diagnostics, and return a clean error response rather than a partially rendered page. Do not expose API credentials, full private document contents, or raw implementation details in public errors.

  1. Authorize the document. Check capability and record-level access before rendering or converting data.
  2. Validate the request. Verify the nonce and validate any submitted post ID, report ID, filename, or options. A nonce does not replace authorization.
  3. Escape output. Escape WordPress values for their HTML context when building the document. Do not insert user-controlled markup without a deliberate sanitization policy.
  4. Protect secrets. Read API credentials from private server configuration and keep them out of logs and responses.
  5. Keep binary output clean. Avoid closing PHP tags in plugin files, remove accidental output buffers before headers, and exit immediately after sending the PDF.
  6. Handle slow conversions. A synchronous download keeps the PHP request open while conversion runs. For long documents, account for PHP/web server timeouts or use a background job and a separate authorized download flow.

7. Performance, reliability, and cost considerations

The research for this implementation does not establish PDFCrowd pricing, conversion speed, limits, or service availability, so check the current vendor materials for those details. On the WordPress side, conversion consumes request time and may retain the PDF in PHP memory when using a byte-returning method. For large files or concurrent downloads, consider file-output methods, controlled temporary storage, and cleanup policies. Avoid regenerating identical documents unnecessarily if the content and access model allow safe caching.

Reliability depends on input reachability and document readiness. URL conversion can fail when a source or asset is private or unavailable to the remote service. HTML-string conversion avoids fetching the WordPress page itself but can still depend on external assets and JavaScript-driven content. Make the document deterministic where possible: render required data server-side, include dependable styles, and set a readiness condition only when client-side rendering is essential.

8. Troubleshooting

Symptom Likely cause Fix
Browser downloads a corrupt PDF or shows HTML PHP warnings, whitespace, a theme template, or an error page was sent before the PDF bytes. Keep the handler in a plugin, remove closing-tag whitespace, clear output buffers before headers, and inspect server logs.
Conversion reports a URL or resource error PDFCrowd’s servers cannot reach the page or one of its assets. Use absolute reachable URLs, make the source intentionally accessible, or submit rendered HTML/file input with the needed assets.
Private page converts as a login screen The remote converter has no WordPress login session or access to the private route. Build the authorized content as an HTML string on the server or use a documented file/archive flow. Do not make sensitive content public just to convert it.
Images or styles are missing Relative paths resolve against an unexpected base, or local/private resources cannot be fetched. Use a suitable base or absolute URLs, inline critical CSS, or package assets with the HTML file.
Dynamic content is blank or incomplete Conversion occurs before JavaScript has populated the page. Prefer server-rendered HTML; otherwise configure an appropriate wait condition and ensure the selected element appears reliably.
WordPress returns 403 The user lacks the chosen capability, record-level authorization failed, or the nonce is missing/invalid. Confirm the form action and nonce action match the handler; then check the intended capability and document ownership/access rules.
Class not found or package errors Composer dependencies or the autoloader are not available in the plugin runtime. Install pdfcrowd/pdfcrowd in the deployed project and load the correct Composer autoloader before constructing the client.
Request times out The PHP/web server request budget is shorter than the conversion and download work. Reduce document complexity, use file output where appropriate, review server timeout settings, or move generation to a background workflow.
Conversion error details are missing The exception is swallowed or only a generic public error is recorded. Catch Pdfcrowd\\Error, log the exception on the server, and keep the public response generic. Do not log secrets.

Or skip the browser setup

If the task is capturing a webpage as an image or PDF rather than generating a PDF from WordPress content, ScreenshotNeo is a website screenshot API and MCP server. It accepts one GET request with a URL and returns a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for request options.

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 accepts cookie banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up free for 1,000 screenshots a month, no card required.

FAQ

Can I use this for a logged-in WordPress page?

Yes, if the handler authorizes the current user, builds the document from data that user may access, and sends the resulting HTML string for conversion. A remote URL conversion does not automatically share the user’s WordPress session.

Should I use AJAX for a PDF download?

Not for a basic file download. A normal form POST to admin-post.php can return the PDF directly. Use admin-ajax.php only when the surrounding interface needs an AJAX workflow.

Does a nonce make the download secure?

No. It verifies request intent, but access control still requires capability and document-specific authorization checks.

Can I generate the PDF without saving it on the WordPress server?

Yes. convertString() returns bytes that the handler can send directly. Consider memory use for large outputs and use a file-output method when that better fits the application.