Skip to content

blitz-html / blitz-dom: the doctype is dropped; there is no DocumentType node

Generated from repros/blitz-html-doctype-dropped/README.md when the site was built at 7aa23e2.

Works around it: when scripting is enabled, crates/niso-core/src/loading.rs parses through a sink that wraps blitz’s and keeps the doctype html5ever reports, and niso adds a DocumentType node of its own (a blitz comment with its name and ids on the side, crates/niso-core/src/api/documents.rs). Its own initial document gets an html doctype the same way. Without scripting, DocumentHtmlParser::parse_into_mutator still drops it.

DocumentHtmlParser parses with TreeBuilderOpts { drop_doctype: true, .. } (packages/blitz-html/src/html_sink.rs:111,151) and NodeData has the Doctype variant commented out (packages/blitz-dom/src/node/node.rs:908-910). Per the HTML parser and DOM, the document’s children are a DocumentType node followed by <html>.

document children expected: ["doctype", "<html>"]
document children actual: ["<html>"]

(NodeData has no variant for a doctype today, which is the bug; the repro names any node kind it does not know doctype, so it passes once blitz adds one.)

Terminal window
CARGO_TARGET_DIR=~/.capy/work/repro-target cargo run

Exit status 1 while the bug reproduces, 0 once fixed. On Ubuntu, blitz needs sudo apt-get install -y libfontconfig-dev pkg-config.

Reproduces. Blitz main was at be60597f67b3cece0456d26e8d7ff5a88600bbc5 when tested (2026-11-08, git ls-remote https://github.com/DioxusLabs/blitz HEAD), the same commit niso pins, so the pinned result is also the main result.

None found. Searched DioxusLabs/blitz issues and PRs (all 1444, titles and full text) for doctype, DocumentType, drop_doctype.

Title: HTML parsing drops the doctype: no DocumentType node in blitz-dom

Body:

blitz-html parses with drop_doctype: true and blitz-dom’s NodeData has Doctype commented out, so a parsed document has no DocumentType child. Anything built on blitz-dom that exposes the DOM cannot implement document.doctype, Node.nodeType == 10, DOMImplementation.createDocumentType or serialize the doctype (Acid3 test 18, WPT dom/nodes/Document-doctype.html).

use blitz_dom::{DocumentConfig, NodeData};
use blitz_html::HtmlDocument;
fn main() {
let doc = HtmlDocument::from_html("<!DOCTYPE html><html><head></head><body></body></html>", DocumentConfig::default());
let first = doc.get_node(doc.root_node().children[0]).unwrap();
// expected a doctype node; actual: the <html> element
assert!(!matches!(first.data, NodeData::Element(_)));
}

Tested at be60597f67b3cece0456d26e8d7ff5a88600bbc5. A fix: restore NodeData::Doctype { name, public_id, system_id }, create it in the sink’s append_doctype_to_document, set drop_doctype: false, and teach layout/serialization to skip/emit it. The sink already receives the quirks mode (see the separate quirks-mode issue).