HTMLRewriter (lol-html)
htmlRewrite applies declarative rules to HTML right in the server-render path. The native lol-html engine (the same streaming rewriter behind Bun's HTMLRewriter) walks the document once and applies each action by CSS selector — no virtual DOM, no tree to parse, and no per-element JavaScript callback. Perfect for injecting a CSP nonce, rewriting URLs to a CDN, hardening external links, or injecting fragments — all at streaming speed.
Tip
A few real use cases, all shown below: CSP nonces — set a
nonce attribute on every <script> for a strict Content-Security-Policy; CDN rewriting — prefix every relative src / href with your CDN origin; hardening — add rel="noopener noreferrer" to every target="_blank" (anti tabnabbing); and fragment injection (banners, comments, analytics tags) without touching the rest of the markup.Input
<div><img src="/hero.png"><a href="https://ext.com" target="_blank">ext</a><script>x()</script></div>Rules
import { htmlRewrite, type HtmlRule } from "@bext-stack/framework";
const input =
`<div><img src="/hero.png"><a href="https://ext.com" target="_blank">ext</a><script>x()</script></div>`;
const rules: HtmlRule[] = [
{ selector: "img[src]", prefixAttribute: ["src", "https://cdn.example.com"] },
{ selector: "a[target=_blank]", setAttribute: ["rel", "noopener noreferrer"] },
{ selector: "script", setAttribute: ["nonce", "DEMO123"] },
{ selector: "div", appendHtml: "<!-- rewritten by bext HTMLRewriter -->" },
];
// Runs natively at SSR via the lol-html bridge (__htmlRewrite).
const output = htmlRewrite(input, rules);Output (rewritten natively at render)
<div><img src="https://cdn.example.com/hero.png"><a href="https://ext.com" target="_blank" rel="noopener noreferrer">ext</a><script nonce="DEMO123">x()</script><!-- rewritten by bext HTMLRewriter --></div>