Skip to content

NextPDF Cloudflare edge-rendering bridge — overview

nextpdf/cloudflare is an edge-rendering bridge. Your PHP application holds the Hypertext Markup Language (HTML), and a Cloudflare Worker holds the headless browser. The bridge sends the HTML to the Worker over Hypertext Transfer Protocol Secure (HTTPS) and receives rendered Portable Document Format (PDF) bytes. No headless browser runs inside your PHP process, and the bridge does not require a local Chromium binary on the path it owns.

The package belongs to the NextPDF ecosystem and depends on nextpdf/core^3.0. It is wire-protocol code: it builds a JavaScript Object Notation (JSON) request, validates the input and destination, sends the request through a PHP Standards Recommendation 18 (PSR-18) client, and parses the response into a typed result object. The Worker implementation is outside this package. This bridge speaks to the Worker you deploy.

The defining characteristic of this bridge is that HTML crosses a network boundary and reaches a browser engine you do not directly control. Every security control in the package exists because of that boundary.

  • HTML is validated before it leaves the PHP process (CloudflareSecurityPolicy::validate()).
  • The destination Uniform Resource Locator (URL) is validated before the request is sent (CloudflareSecurityPolicy::validateWorkerUrl()), then re-validated at request time to close the time-of-check/time-of-use window (assertPinsStillValid()).
  • The transport can pin the resolved Internet Protocol (IP) set and the server certificate’s public key (Transport\PinnedCurlTransport).

If you are evaluating this bridge for production, read /integrations/cloudflare/security-and-operations/ before /integrations/cloudflare/quickstart/. The security model is not an add-on; it explains why the package is shaped this way.

CapabilityBacked by
Render HTML to PDF via a Cloudflare WorkerCloudflareHtmlRenderer::render()
Reachability probe (Hypertext Transfer Protocol (HTTP) HEAD)CloudflareHtmlRenderer::isAvailable()
Vendor-neutral transportPSR-18 ClientInterface injection
Input hardening (size, base64 bomb, meta-refresh)CloudflareSecurityPolicy::validate()
Server-side request forgery (SSRF) / Domain Name System (DNS)-rebinding defenseCloudflareSecurityPolicy::validateWorkerUrl() + assertPinsStillValid()
Transport Layer Security (TLS) public-key pinning, pinned DNS at the cURL layerTransport\PinnedCurlTransport
Local Chrome fallback when the Worker is unreachableContract\LocalRendererFactoryInterface
Binary and JSON (base64) response parsingCloudflareResponseParser
Edge telemetry (render time, edge location, content height)CloudflareRenderResult
Custom fonts from an R2 bucketCloudflareRenderPayload (r2FontBucket, fontFiles)
Application Programming Interface (API) protection layer (key auth, payload size, rate limiting)ApiProtection
PDF archival to R2 over the S3-compatible APIR2ArchiveManager

Every row maps to a class in the NextPDF\Cloudflare namespace. Each row is verified against that class’s behavior and its test, not a specification document.

  • It does not run a browser. The Worker does.
  • It does not deploy or configure your Worker. You own that artifact.
  • It does not sign PDFs. Signing belongs to nextpdf/core or the commercial editions. When you need signing, render first, then sign the returned bytes with the engine. NextPDF Pro provides PAdES B-B signing. Long-term-validation profiles are an Enterprise capability.
  • It does not assert any Cloudflare platform capacity or limit. The only size and time limits this documentation states are the ones this package enforces through its own configuration (see /integrations/cloudflare/configuration/).

The bridge carries two distinct, complementary policies. Conflating them is the most common review error. Here is each one.

  • HTML security policy (HtmlSecurityPolicyInterface, default NextPDF\Html\DefaultHtmlSecurityPolicy, supplied by nextpdf/core): content filtering at the parse layer, applied before content reaches the Worker. Retrieve it with getHtmlSecurityPolicy().
  • Cloudflare security policy (CloudflareSecurityPolicy, static): transport-layer concerns: input size, base64 decompression-bomb detection, meta-refresh blocking, HTTPS enforcement, and SSRF / DNS-rebinding defense for the Worker URL.

The renderer’s own docblock states this separation. This page restates it because production reviewers need both names on one screen.

A single render() call follows this observable sequence. The sequence is read directly from CloudflareHtmlRenderer::render().

  1. Configuration completeness check (workerUrl and apiToken non-empty). If the check fails, the bridge either falls back to a local renderer or throws CloudflareNotAvailableException.
  2. HTML validation against the configured maximum size, base64 URI ceiling, and meta-refresh ban.
  3. Worker URL validation, which resolves the host and returns the vetted IP set.
  4. Payload construction (CloudflareRenderPayload).
  5. A time-of-use re-check confirms that the host’s DNS answer has not changed since step 3.
  6. The HTTP POST is sent through the pinned cURL transport when an IP set or Subject Public Key Info (SPKI) pin set exists and a PSR-17 ResponseFactory was supplied, otherwise through the injected PSR-18 client.
  7. The response is parsed into a CloudflareRenderResult.

Any throwable other than CloudflareRenderException triggers the fallback path. CloudflareRenderException (an HTTP error or a malformed response from the Worker) is rethrown unchanged. It is a Worker-side failure, not a reachability failure, so the bridge does not fall back.

  • /integrations/cloudflare/install/ — install the package and a PSR-18 client.
  • /integrations/cloudflare/configuration/ — every configuration field, with its source-verified default.
  • /integrations/cloudflare/quickstart/ — your first runnable render.
  • /integrations/cloudflare/production-usage/ — fallback, telemetry, R2 archival, API protection.
  • /integrations/cloudflare/security-and-operations/ — operational detail for the trust boundary.
  • /integrations/cloudflare/troubleshooting/ — failure modes mapped to exceptions.
  • /integrations/cloudflare/boot-and-discovery/ — how the bridge plugs into a host framework.
  • /integrations/cloudflare/integration/ — driving NextPDF through Cloudflare services.