Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG tags are not rendering #225

Open
rahujoshi opened this issue Apr 29, 2022 · 7 comments
Open

SVG tags are not rendering #225

rahujoshi opened this issue Apr 29, 2022 · 7 comments

Comments

@rahujoshi
Copy link

https://codesandbox.io/s/target-first-child-css-styled-components-forked-7p64n0?file=/src/index.js

I am getting SVG string from the backend I want to render it in my React app...But I am not able to achieve it.. see the code link at the top

@milesj
Copy link
Owner

milesj commented Apr 29, 2022

@rahujoshi Interweave was only designed for HTML as it parses it with the DOM, SVG wont work.

I'm not sure why you would run SVGs through interweave anyways.

@dantabel
Copy link

dantabel commented Jul 11, 2022

@rahujoshi I have this issue too. SVG attributes use camel case like viewBox but Interweave converts all attributes to lowercase. I have inline SVGs as part of a HTML string hence needing to use Interweave. My only solution was to use dangerouslySetInnerHTML instead.

@milesj inline SVGs are valid in HTML (e.g. https://www.w3schools.com/html/html5_svg.asp) so the DOM should be able to parse it fine. If you have SVGs as part of a HTML string you would expect them to be rendered I would have thought. With allowElements and allowAttributes set to true, it's just the camelCase attributes being lowercased that stop it from rendering properly.

@milesj
Copy link
Owner

milesj commented Jul 11, 2022

It depends on whether createHTMLDocument supports parsing SVG correctly or not, which is what Interweave uses under the hood.

I can't recall off the top of my head.

@dantabel
Copy link

Thanks for your response. I've just had a play around in code sandbox. You need to use createElementNS to create an element in the SVG namespace, using createElement didn't work. So doc.createElementNS("http://www.w3.org/2000/svg", "svg") works.

I understand that this probably makes this too much of a hassle for you as you'd have to identify all of the SVG elements and process them differently.

@dantabel
Copy link

To solve my issue I've written the following transform function. I know it's not particularly safe, but I trust the source HTML, so it works for me.

const transform = (node: HTMLElement, children: Node[]): React.ReactNode => {
    const namespaces = [
        'http://www.w3.org/1998/Math/MathML',
        'http://www.w3.org/2000/svg'
    ]
    if(node.namespaceURI && namespaces.includes(node.namespaceURI)){
        const attributes:{[att:string]: string|null} = {}
        node.getAttributeNames().forEach(attName => {
            attributes[attName] = node.getAttribute(attName)
        })
        return React.createElement(node.tagName, attributes, children) 
    }
    return undefined
}

@milesj
Copy link
Owner

milesj commented Jul 12, 2022

Awesome transformer. This may be a quick win to support it in core in the future.

@overtureweb
Copy link

@rahujoshi Interweave was only designed for HTML as it parses it with the DOM, SVG wont work.

I'm not sure why you would run SVGs through interweave anyways.

I'm using Interweave to parse an HTML doc received in an AJAX response to an API call. Some of the HTML docs contain SVG elements. I don't think it's unreasonable to assume that could be the case. IW is an awesome utility and would love to see support for SVG elements added. FTM I'm using @dantabel's excellent suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants