NextPDF Cloudflare boot and discovery
At a glance
Section titled “At a glance”The bridge includes no service provider, bundle, or auto-discovery hook
of its own. It is a set of final classes with explicit constructors.
Here, “discovery” means choosing the collaborators to inject and binding
them in your framework’s container. This page describes that wiring. It
does not invent a registration mechanism that the package does not have.
How the renderer bridge is discovered
Section titled “How the renderer bridge is discovered”You construct CloudflareHtmlRenderer; you do not discover it. Its
dependencies are PHP Standard Recommendation (PSR) contracts: PSR-18,
PSR-17, and PSR-3, plus the package’s own config and contract types. Any
framework that can build those collaborators can build the renderer. The
package depends only on PSR contracts; the tests/Unit/Architecture/PsrConformanceTest.php
test asserts that no concrete client is coupled to the renderer. Your
host application can reuse its existing HTTP client binding unchanged.
The Laravel, Symfony, and CodeIgniter NextPDF adapters reuse that same
PSR-18 binding. This package adds no framework package of its own.
Boot sequence
Section titled “Boot sequence”Resolve the collaborators in this order, matching the constructor of
CloudflareHtmlRenderer:
- Resolve the PSR-18
ClientInterfacefrom the application’s existing HTTP client binding. - Resolve the PSR-17
RequestFactoryInterfaceandStreamFactoryInterface; also resolveResponseFactoryInterfacewhen you want the pinned cURL transport. - Build a
CloudflareRendererConfigfrom the resolved configuration (see “Configuration resolution order”). - Optionally resolve a PSR-3
LoggerInterface, aLocalRendererFactoryInterface, and an explicitHtmlSecurityPolicyInterface. - Construct
CloudflareHtmlRendererwith those collaborators.
None of these steps contacts the network. The first network interaction
happens when you call render() or isAvailable().
Container bindings
Section titled “Container bindings”A representative binding (framework-agnostic pseudocode):
<?php
declare(strict_types=1);
use NextPDF\Cloudflare\CloudflareHtmlRenderer;use NextPDF\Cloudflare\CloudflareRendererConfig;use Psr\Http\Client\ClientInterface;use Psr\Http\Message\RequestFactoryInterface;use Psr\Http\Message\ResponseFactoryInterface;use Psr\Http\Message\StreamFactoryInterface;use Psr\Log\LoggerInterface;
$container->singleton(CloudflareHtmlRenderer::class, function ($c) { return new CloudflareHtmlRenderer( config: CloudflareRendererConfig::fromArray($c->get('config')['cloudflare']), httpClient: $c->get(ClientInterface::class), requestFactory: $c->get(RequestFactoryInterface::class), streamFactory: $c->get(StreamFactoryInterface::class), logger: $c->get(LoggerInterface::class), responseFactory: $c->get(ResponseFactoryInterface::class), );});Configuration resolution order
Section titled “Configuration resolution order”The package does not read environment variables itself. It accepts a
fully formed CloudflareRendererConfig. In the host application, resolve
configuration in this order: environment variables first, then published
or framework config, then the package defaults baked into the constructor
(documented in /integrations/cloudflare/configuration/).
CloudflareRendererConfig::fromArray() applies the constructor defaults
for any absent or incorrectly typed key, so a partial config array falls
back predictably instead of failing.
Diagnostics
Section titled “Diagnostics”CloudflareRendererConfig::isValid() is the boot-time signal. It is a
pure check that both workerUrl and apiToken are non-empty and makes
no network call, so you can use it as a deploy gate. The runtime signal
is CloudflareHtmlRenderer::isAvailable(), an authenticated HTTP HEAD
that returns true for a status below 500 and false (never
throwing) otherwise, so you can use it as a readiness probe. A passing
probe is a hint, not a guarantee: the subsequent POST can still fail.
See also
Section titled “See also”- /integrations/cloudflare/integration/ — the complete integration walkthrough.
- /integrations/cloudflare/overview/ — what the bridge is and which boundary it crosses.
- /integrations/cloudflare/configuration/ — every field and default.
- /integrations/cloudflare/security-and-operations/ — when the pinned transport activates.