react-html-parser icon indicating copy to clipboard operation
react-html-parser copied to clipboard

SVG viewBox not working well

Open hrahimi270 opened this issue 6 years ago • 14 comments

Hi there. I'm working with SVG and I need to parse my SVG to HTML for React. Now, I realized that viewBox property has an issue. Parsed SVG must have a viewBox but react-html-parser make it viewbox with small b. It makes a mistake to render SVG especially in responsive.

Please fix this. Reagards.

hrahimi270 avatar Feb 10 '19 10:02 hrahimi270

Ditto. Please fix, related to https://github.com/wrakky/react-html-parser/issues/45

DavidLozzi avatar Feb 13 '19 18:02 DavidLozzi

I got a valid workaround working...

  renameProp = (oldProp, newProp, { [oldProp]: old, ...others }) => ({
    ...others,
    [newProp]: old
  });

  render() {
      ...
      const htmlOutput = ReactHtmlParser(htmlData, { transform: this.transform });
      const props = this.renameProp('viewbox', 'viewBox', htmlOutput[1].props);
      const newOutput = [];
      newOutput.push(null); //unsure if they're all null, but in my example I was seeing null in the first position
      newOutput.push({
        ...htmlOutput[1],
        props
      });

      return (
        <div className="slide-medium">
          {newOutput}
        </div>
      );

This is still an early POC, but thought I'd pass it along

DavidLozzi avatar Feb 14 '19 17:02 DavidLozzi

Unfortunately, this works for viewBox but not a slew of other properties that are incorrect throughout the svg file.... still looking for a solution

DavidLozzi avatar Feb 19 '19 15:02 DavidLozzi

Also having trouble with this but with react routers Link component, it is converted to link and so doesn't work.

cj-clifton avatar Apr 15 '19 03:04 cj-clifton

Try this https://stackoverflow.com/a/43558609/6755649 and make sure you pass the Components that you want rendered correctly (without being converted to lowercase html tags) to JsxParser in the components prop

cj-clifton avatar Apr 15 '19 10:04 cj-clifton

I ended up skipping this library altogether, there were too many issues with the SVG, and just setting the content like: dangerouslySetInnerHTML={{ __html: '<svg>...</svg>' }}

DavidLozzi avatar Jul 16 '19 15:07 DavidLozzi

I've used svg-to-jsx library to convert first to jsx and then run it by this one. All of the properties are read correctly except "preserveaspectratio" which is reverted back to lowercase.

george2seven avatar Jul 23 '19 12:07 george2seven

I came into the same problem when rendering KaTeX math formula, I wrote this to fix.

transform = (node, index) => {
  if (node.type === 'tag' && node.name === 'svg') {
    const child = node.children[0];
    const { width, height, viewbox, preserveaspectratio } = node.attribs;
    return (
      <svg
        key={index}
        width={width}
        height={height}
        viewBox={viewbox}
        preserveAspectRatio={preserveaspectratio}
      >
        {convertNodeToElement(child, index, this.transform)}
      </svg>
    );
  }
}

and

...
const renderedPost = HtmlParser(post, { transform: this.transform })
...

Yangjiaxi avatar Jul 28 '19 20:07 Yangjiaxi

I tried @Yangjiaxi 's fix but i still had some issues, tried this https://www.npmjs.com/package/html-react-parser and it was fixed.

Natedeploys avatar Aug 20 '19 10:08 Natedeploys

parse(svgList[key].toString(), { replace: attribs => { if(attribs.name === 'symbol'){ attribs.attribs.viewBox = attribs.attribs.viewbox delete attribs.attribs.viewbox } } })

RenatMG avatar Jan 06 '20 10:01 RenatMG

The related source code is here: https://github.com/wrakky/react-html-parser/blob/master/src/utils/htmlAttributesToReact.js#L41

Not sure what the correct fix would be. But adding viewbox: 'viewBox' to the map in ReactAttributes.js works.

jouni avatar May 28 '20 08:05 jouni

Note, that other svg features stop working as well, for example:

  • gradientUnits attribute which gets converted to gradientunits
  • <linearGradient> element, which is converted to <lineargradient>.

jouni avatar Jun 23 '20 11:06 jouni

i think that this lib is using htmlparse2 library and there is an option from htmlparser2 to not render lower case attributes of nodes. So i don't know if this can be used as an option inside this library, but it should...

jerome-diver avatar Jul 26 '20 16:07 jerome-diver

{ReactHtmlParser(svgHtmlString, { transform: transformFn })}
function transformFn(node, index) {
  if (node.name === "svg") {


    const { viewbox, ...rest } = node.attribs;

    return (
      <svg   {...rest} viewBox={viewbox}>
        {node.children.map((child, index) => {
          return convertNodeToElement(child, index, transformFn)
        })}
      </svg>
    )
  }
}

cr7cr8 avatar Sep 03 '21 10:09 cr7cr8