Assets Images, CSS, fonts · 8 min read

Asset Pipeline

BladePDF resolves images, stylesheets, fonts, JavaScript files, SVG files, and other local references through the framework-agnostic core. Laravel configures safe defaults; cloud templates can use dashboard assets and per-request overrides.

Local HTML assets

When you call fromView(), the package first renders your Laravel view to HTML, scans it for local file references, uploads those files with the render request, and rewrites references to asset:///... URLs.

resources/views/pdf/invoice.blade.php
blade
 1<link rel="stylesheet" href="{{ asset('css/invoice.css') }}">
 2<img src="{{ asset('images/logo.png') }}" alt="Logo">

The Laravel adapter maps URL paths through public_path(), searches public_path() and storage_path('app'), and recognizes the APP_URL host plus localhost, 127.0.0.1, and ::1. The plain PHP and Node.js SDKs read no local files until you configure roots explicitly.

Allowed roots and security

Every automatically discovered path is resolved to its canonical filesystem location and must remain inside an allowed root. Directory traversal, absolute paths or file:// URLs outside a root, and symlinks that escape a root are rejected. Laravel deliberately does not allow base_path(), preventing document HTML from reading .env and application source by default.

Publish config/bladepdf.php and append narrowly scoped directories to asset_roots when documents need additional files. See the Laravel 2.0 root migration, PHP SDK roots, or Node.js SDK roots.

Scanned references

Location Examples
HTML attributessrc, href, poster, data-src, data-href
Responsive imagessrcset
Inline stylesstyle="background:url(...)"
Style blocks<style> with CSS url() and @import
CSS filesNested url() references such as fonts and background images
External files<script src> JavaScript and referenced SVG files

External URLs

External http:// and https:// URLs are preserved. Availability depends on your plan and network settings. Unsafe destinations and unsupported protocols are blocked.

Protocol-relative CDN URLs, data:, blob:, javascript:, mailto:, tel:, and existing asset:/// references are not rewritten. Query strings and fragments are preserved, including font.woff2?v=1 and sprite.svg#icon.

JavaScript and SVG are opaque

The referenced files are transferred, but their contents are not traversed. BladePDF does not parse JavaScript imports, dynamic imports, fetch(), runtime URLs, SVG contents, or dependencies inside SVG.

Disable automatic resolution

Automatic asset resolution is enabled by default. If you want BladePDF to leave your HTML and CSS references untouched, disable it globally with an environment variable:

.env
env
 1BLADEPDF_AUTO_RESOLVE_ASSETS=false

Or disable it for one render:

Single render
php
 1return BladePDF::fromView('pdf.invoice', ['invoice' => $invoice])
 2    ->withoutAssetResolution()
 3    ->render()
 4    ->response();

Manual assets added with withAsset() or overrideAsset() are still uploaded. Only the automatic scan-and-rewrite step is skipped. If you prefer a toggle-style call, resolveAssets(false) is equivalent to withoutAssetResolution().

Manual assets

Use withAsset() when your HTML already references an asset:///... URL, when you want full control over the request asset name, or when the caller intentionally approves one file outside the automatic roots.

Manual asset
php
 1$html = '<img src="asset:///brand-logo.png">';
 2
 3return BladePDF::fromHtml($html)
 4    ->withAsset(public_path('images/logo.png'), 'brand-logo.png', 'image/png')
 5    ->render()
 6    ->response();

Cloud template assets

Cloud templates can reference dashboard assets using the asset:/// scheme. If a request provides an override with the same asset name, the uploaded file is used for that render only.

Node.js files and generated assets

The Node.js SDK uses assetFile() for an intentional filesystem file and assetData() for a Buffer, Uint8Array, or ArrayBuffer. A generated asset requires an explicit target:

Generated chart
typescript
 1render.assetData(chartBuffer, {
 2  target: 'chart.png',
 3  mimeType: 'image/png',
 4});
Cloud template
blade
 1<img src="asset:///bladepdf-old-logo-colored.png" alt="Logo">
 2<link rel="stylesheet" href="asset:///invoice.css">

Per-request overrides

Use overrideAsset() to replace a cloud asset for one render request. This is useful for tenant logos, one-off attachments, and generated images.

Override
php
 1return BladePDF::fromTemplate('invoice.standard', $context)
 2    ->overrideAsset('bladepdf-old-logo-colored.png', public_path('tenant-logo.png'))
 3    ->render()
 4    ->response();
Use simple override names

Override targets may contain letters, numbers, dots, underscores, and hyphens. Use names such as logo.png or invoice.css.

Asset metrics

Render details include asset timing and counts:

  • assets_resolve_ms
  • assets_resolved_count
  • assets_cache_hits
  • assets_uploaded_count

These metrics appear in the dashboard render detail and help explain how assets affected a render.

Troubleshooting

Problem Check
Image missing from local view renderConfirm the file exists under public_path() or is reachable as a local host asset.
Cloud asset missingConfirm the asset exists in the dashboard and the template references the correct asset:///... key.
Override rejectedUse a simple override name like logo.png, not a nested path.
External URL blockedUse stored assets or confirm your plan allows internet access.