{"record":{"id":"176bd65ee0c80410","repo":"swc-project/swc","slug":"html-start-tag-tag-name-in-a-foreign-namespace","errorCode":null,"errorMessage":"HTML start tag \"{tag_name}\" in a foreign namespace context","messagePattern":"HTML start tag \"(.+?)\" in a foreign namespace context","errorType":"exception","errorClass":"swc_html_parser::error::Error","httpStatus":null,"severity":"warning","filePath":"crates/swc_html_parser/src/parser/mod.rs","lineNumber":781,"sourceCode":"                        | \"ol\"\n                        | \"p\"\n                        | \"pre\"\n                        | \"ruby\"\n                        | \"s\"\n                        | \"small\"\n                        | \"span\"\n                        | \"strong\"\n                        | \"strike\"\n                        | \"sub\"\n                        | \"sup\"\n                        | \"table\"\n                        | \"tt\"\n                        | \"u\"\n                        | \"ul\"\n                        | \"var\"\n                ) =>\n            {\n                self.errors.push(Error::new(\n                    token_and_info.span,\n                    ErrorKind::HtmlStartTagInForeignContext(tag_name.clone()),\n                ));\n                self.open_elements_stack.pop_until_in_foreign();\n                self.process_token(token_and_info, None)?;\n            }\n            Token::StartTag {\n                tag_name,\n                attributes,\n                ..\n            } if tag_name == \"font\"\n                && attributes\n                    .iter()\n                    .any(|attribute| matches!(&*attribute.name, \"color\" | \"face\" | \"size\")) =>\n            {\n                self.errors.push(Error::new(\n                    token_and_info.span,\n                    ErrorKind::HtmlStartTagInForeignContext(tag_name.clone()),","sourceCodeStart":763,"sourceCodeEnd":799,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_html_parser/src/parser/mod.rs#L763-L799","documentation":"A start tag from the spec's breakout list (b, big, blockquote, body, br, center, code, dd, div, dl, dt, em, embed, h1-h6, head, hr, i, img, li, listing, menu, meta, nobr, ol, p, pre, ruby, s, small, span, strong, strike, sub, sup, table, tt, u, ul, var) was seen while the adjusted current node was in a foreign namespace (crates/swc_html_parser/src/parser/mod.rs:781). The parser records HtmlStartTagInForeignContext, calls pop_until_in_foreign() — force-closing the entire SVG/MathML subtree — and reprocesses the tag with normal HTML rules.","triggerScenarios":"Input like `<svg><p>hi</p></svg>`, `<math><div>x</div></math>`, or any HTML layout/typography tag opened between <svg>/<math> and its matching close tag. Very frequent when a closing </svg> or </math> is missing, so all subsequent page HTML is dispatched as foreign content until a breakout tag appears.","commonSituations":"Authors wrapping page layout in SVG by mistake, WYSIWYG editors injecting <br>/<p> inside SVG islands, template partials that conditionally drop the </svg>, appended HTML after an unclosed <math> formula.","solutions":["Close the <svg>/<math> element before any HTML layout tag; balance the foreign element's open/close pair in the template","Use <svg><foreignObject> when you genuinely need HTML flow content inside SVG (integration points keep HTML rules active there)","Fix the missing </svg> or </math> that swallows the following HTML","Filter ErrorKind::HtmlStartTagInForeignContext(_) if you accept the force-close recovery"],"exampleFix":"<!-- before: <p> breaks out of the svg subtree -->\n<svg><p>Styled text</p></svg>\n\n<!-- after: keep them separate -->\n<svg></svg>\n<p>Styled text</p>\n\n<!-- or embed HTML inside SVG properly: -->\n<svg><foreignObject width=\"200\" height=\"50\"><p>Styled text</p></foreignObject></svg>","handlingStrategy":"validation","validationCode":"const BREAKOUT: &[&str] = &[\"b\",\"big\",\"blockquote\",\"body\",\"br\",\"center\",\"code\",\"dd\",\"div\",\"dl\",\"dt\",\"em\",\"embed\",\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\",\"head\",\"hr\",\"i\",\"img\",\"li\",\"listing\",\"menu\",\"meta\",\"nobr\",\"ol\",\"p\",\"pre\",\"ruby\",\"s\",\"small\",\"span\",\"strong\",\"strike\",\"sub\",\"sup\",\"table\",\"tt\",\"u\",\"ul\",\"var\"];\n\nfn html_breakout_in_foreign(html: &str) -> Option<usize> {\n    let lower = html.to_ascii_lowercase();\n    for root in [\"<svg\", \"<math\"] {\n        let close = format!(\"</{}\", &root[1..]);\n        let mut from = 0;\n        while let Some(rel) = lower[from..].find(root) {\n            let start = from + rel;\n            let end = lower[start..].find(&close).map(|i| start + i).unwrap_or(lower.len());\n            for (i, _) in lower[start..end].match_indices('<') {\n                let rest = &lower[start + i + 1..];\n                let rest = rest.strip_prefix('/').unwrap_or(rest);\n                let name: String = rest.chars().take_while(char::is_ascii_alphanumeric).collect();\n                if BREAKOUT.contains(&name.as_str()) {\n                    return Some(start + i);\n                }\n            }\n            from = end + close.len();\n        }\n    }\n    None\n}","typeGuard":null,"tryCatchPattern":"use swc_html_parser::error::ErrorKind;\n\nlet mut errors = Vec::new();\nlet doc = swc_html_parser::parse_file_as_document(&fm, config, &mut errors)?;\n\nfor err in &errors {\n    if let ErrorKind::HtmlStartTagInForeignContext(tag) = err.kind() {\n        // The svg/math subtree was force-closed at this tag; check if that\n        // truncated content you cared about.\n        log::warn!(\"html tag <{tag}> closed foreign content\");\n    }\n}","preventionTips":["Never put HTML layout tags directly inside <svg>/<math>; close the foreign element first","Use <foreignObject> for HTML-in-SVG (it is an HTML integration point)","Lint templates for unbalanced <svg>/<math> open/close pairs"],"tags":["html","parser","foreign-content","svg","mathml","nesting","breakout-tag","swc"],"backgroundTag":"html-in-foreign-content","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}