HTMLRewriter (lol-html)

htmlRewrite applique des règles déclaratives à du HTML directement dans le chemin de rendu serveur. Le moteur natif lol-html (le même réécriveur en streaming que HTMLRewriter de Bun) parcourt le document une seule fois et applique chaque action par sélecteur CSS — sans DOM virtuel, sans arbre à parser, et sans rappel JavaScript par élément. Idéal pour injecter un nonce CSP, réécrire des URL vers un CDN, durcir les liens externes ou injecter des fragments, le tout à la vitesse du flux.

Astuce
Quelques usages concrets, tous illustrés ci-dessous : nonces CSP — poser un attribut nonce sur chaque <script> pour une politique Content-Security-Policy stricte ; réécriture CDN — préfixer chaque src / href relatif par l'origine de votre CDN ; durcissement — ajouter rel="noopener noreferrer" à chaque target="_blank" (anti tabnabbing) ; et l'injection de fragments (bannières, commentaires, balises analytics) sans toucher au reste du balisage.

Entrée

input.htmlHTML
<div><img src="/hero.png"><a href="https://ext.com" target="_blank">ext</a><script>x()</script></div>

Règles

src/app/examples/html-rewriter/page.tsxTypeScript
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);

Sortie (réécrite nativement au rendu)

output.htmlHTML
<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>