Overview
HTMLRewriter lets you modify HTML responses as they stream through your edge
script. It parses the HTML on the fly and calls your handler functions when it
meets matching elements, comments, or text, so the whole document never has to
be buffered in memory.
Quickstart
A short middleware example:Constructor
Methods
on(selector, handlers)
Registers handlers for elements matching a CSS selector. Returns this for chaining.
A CSS selector. See supported selectors below.
An object with optional handler functions. Each handler can be sync or async.
onDocument(handlers)
Registers document-level handlers. Returns this for chaining.
transform(response)
Applies all registered handlers to the response body and returns a new Response.
Response with:
- The same headers (minus
Content-Length, since the body length may change) - A streaming body with the transformed HTML
Handler types
Element
Passed toelement handlers. Represents an HTML opening tag.
Properties
Attribute methods
getAttribute(name)
Returns the value of the attribute with the given name, or null if the attribute does not exist.
Returns: string | null
hasAttribute(name)
Returns whether the element has an attribute with the given name.
Returns: boolean
setAttribute(name, value)
Sets the value of the attribute with the given name. Adds the attribute if it does not exist.
Returns: Element, the element itself, for chaining.
removeAttribute(name)
Removes the attribute with the given name. No-op if the attribute does not exist.
Returns: Element, the element itself, for chaining.
Setters return the element itself, so calls can be chained:
Content mutation methods
All content mutation methods acceptcontent as a string, ReadableStream<Uint8Array>, or Response,
and an optional options object. They all return Element for chaining.
The content to insert. Strings are inserted directly. Streams and Response bodies are consumed and piped into the output.
When
true, content is inserted as raw HTML. When false, content is escaped as text.before(content, options?)
Inserts content immediately before the element’s opening tag.
Returns: Element
after(content, options?)
Inserts content immediately after the element’s closing tag.
Returns: Element
prepend(content, options?)
Inserts content at the beginning of the element, right after the opening tag.
Returns: Element
append(content, options?)
Inserts content at the end of the element, right before the closing tag.
Returns: Element
replace(content, options?)
Replaces the entire element (opening tag, content, and closing tag) with the provided content.
Returns: Element
setInnerContent(content, options?)
Replaces the element’s inner content, keeping the opening and closing tags.
Returns: Element
Removal methods
remove()
Removes the element and all of its content (opening tag, children, closing tag).
Returns: Element
removeAndKeepContent()
Removes the element’s opening and closing tags but keeps the inner content in place.
Returns: Element
End tag handler
onEndTag(handler)
Registers a handler that is called when the element’s closing tag is encountered.
A callback receiving the
EndTag object. Can be async.void
Comment
Passed tocomments handlers.
Properties
Methods
before(content, options?)
Inserts content immediately before the comment.
When
true, content is inserted as raw HTML. When false, content is escaped as text.Comment
after(content, options?)
Inserts content immediately after the comment.
When
true, content is inserted as raw HTML. When false, content is escaped as text.Comment
replace(content, options?)
Replaces the comment with the provided content.
When
true, content is inserted as raw HTML. When false, content is escaped as text.Comment
remove()
Removes the comment from the document.
Returns: Comment
TextChunk
Passed totext handlers. Note: a single text node may be split across multiple chunks.
Properties
Methods
before(content, options?)
Inserts content immediately before the text chunk.
When
true, content is inserted as raw HTML. When false, content is escaped as text.TextChunk
after(content, options?)
Inserts content immediately after the text chunk.
When
true, content is inserted as raw HTML. When false, content is escaped as text.TextChunk
replace(content, options?)
Replaces the text chunk with the provided content.
When
true, content is inserted as raw HTML. When false, content is escaped as text.TextChunk
remove()
Removes the text chunk from the document.
Returns: TextChunk
EndTag
Passed toonEndTag handlers.
Properties
Methods
before(content, options?)
Inserts content immediately before the end tag.
When
true, content is inserted as raw HTML. When false, content is escaped as text.EndTag
after(content, options?)
Inserts content immediately after the end tag.
When
true, content is inserted as raw HTML. When false, content is escaped as text.EndTag
remove()
Removes the end tag from the document.
Returns: EndTag
Doctype
Passed todoctype handlers. All properties are read-only.
Properties
DocumentEnd
Passed toend handlers.
Methods
append(content, options?)
Appends content at the end of the document.
When
true, content is inserted as raw HTML. When false, content is escaped as text.DocumentEnd
Supported CSS selectors
The following CSS selectors are supported, based on the W3C Selectors Level 4 specification.Examples
Rewrite links
Inject a script
Remove elements
Async handler
Handlers can return aPromise for async operations like sub-requests.
Class-based handlers
Instead of inline objects, you can define handler classes and pass instances to.on() or .onDocument().
Document handler class
Async class handler
Class methods can beasync just like inline handlers.
Multiple selectors
Chain multiple.on() calls to handle different elements independently.
References
- Edge Side Includes - W3 Reference of ESI.
- W3C Selectors 4 Specification
- WASM HTMLRewriter Implementation - If you want to use locally