HtmlRenderer delegates tag construction and HTML5 attribute escaping to ui-awesome/html. Invalid UTF-8 bytes are
substituted rather than passed through. Required attributes such as src, href, rel, type, and nonce cannot be
overridden.
Inline module source is application-owned executable JavaScript, not untrusted text. The renderer prevents a literal
case-insensitive </script sequence from terminating the script element, but it does not sanitize JavaScript. Never build an
InlineModule by interpolating untrusted input without a safe JavaScript serialization strategy.
HtmlRenderOptions accepts per-asset-type attributes and an optional per-asset callback:
use PHPForge\Vite\Asset\AssetInterface;
use PHPForge\Vite\Asset\ModuleScript;
use PHPForge\Vite\Html\HtmlRenderOptions;
$options = HtmlRenderOptions::create()
->withModuleScriptAttributes(['crossorigin' => true])
->withStylesheetAttributes(['media' => 'screen'])
->withAttributeProvider(
static fn(AssetInterface $asset): array => $asset instanceof ModuleScript
? ['data-entry' => 'application']
: [],
);Names must start with a letter or underscore and continue with letters, digits, underscores or hyphens. Values may be
strings, integers, floats, booleans or null: true emits a valueless attribute, false and null omit it. Inline
event handlers, style, required renderer attributes, nonce overrides and duplicate names (case-insensitive) are
rejected.
A callback value replaces a per-type value with the same key.
Generate a cryptographically random nonce for each HTTP response, include it in the application's Content-Security-Policy header, and pass the same base64 or base64url value to the renderer:
use PHPForge\Vite\Html\HtmlRenderer;
use PHPForge\Vite\Html\HtmlRenderOptions;
$nonce = base64_encode(random_bytes(18));
header("Content-Security-Policy: script-src 'nonce-{$nonce}' 'strict-dynamic'; object-src 'none'; base-uri 'none'");
$html = HtmlRenderer::create()->render(
$vite->resolve(),
HtmlRenderOptions::create()->withNonce($nonce),
);The renderer places the nonce on every generated script and link tag. The complete CSP header, the per-response nonce lifecycle and every other directive stay with the application.
Dev servers usually need extra connect-src origins for HTTP and WebSocket HMR. Add those to the application's
development policy only; this package never weakens CSP on its own.