You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SVG attribute and element names are lowercased, which breaks SVG rendered in the browser #467
Comark Version: 0.7.0 (seen through @comark/vue 0.7.0)
Framework: Vue (also reproduced in Nuxt 4.5.2 with @comark/nuxt 0.7.0, client render)
Comark Version
0.7.0
Reproduction
npm i comark@0.7.0
// repro.mjsimport{parseMarkdown}from'comark'constdoc=awaitparseMarkdown('<svg viewBox="0 0 10 10"><linearGradient id="g"></linearGradient></svg>')console.log(JSON.stringify(doc.nodes))// svg props contain "viewbox"; the child tag is "lineargradient"
What a client-side renderer then does with those nodes (paste into a browser console):
constNS='http://www.w3.org/2000/svg'constsvg=document.createElementNS(NS,'svg')svg.setAttribute('viewbox','0 0 10 10')console.log(svg.getAttribute('viewBox'))// null: the viewBox is not appliedconsole.log(document.createElementNS(NS,'lineargradient').constructor.name)// SVGElement, not SVGLinearGradientElement
Description
SVG attribute and element names are case-sensitive: viewBox and linearGradient work; viewbox and lineargradient do not. Comark lowercases HTML attribute names everywhere, and element names in inline HTML. For HTML elements this is harmless, but it breaks SVG.
Server-rendered HTML hides the problem: the browser's HTML parser fixes the case when it reads the page. When a framework renderer builds the SVG in the browser (client-side navigation, live preview, streaming), the wrong-case attribute is ignored and gradient elements become generic elements, so icons and logos render at the wrong size or without gradients.
A multi-line HTML block keeps linearGradient but still lowercases viewBox, so the two parse paths are inconsistent with each other.
HTML element names should stay lowercased; the existing SPEC SPEC/HTML/inline.md (<Hello> becoming hello) must keep passing. Only SVG (and optionally MathML) content needs case restoration, as the HTML standard's tree-construction rules do.
Logs
Not applicable; the reproduction above shows the full output.
Activity
adamdehaven commentedon Oct 15, 2026
This should be resolved via #401
Original discussion here: #469 (comment)