Search code examples
htmlreactjssvgdangerouslysetinnerhtmlforeignobject

HTML in SVG textPath?


In my React app, I'm trying to get some text, containing html spans (like so: "Made with ❤️ since 2023" to display in an SVG text path (which itself follows a circle path).

I have tried wrapping this html using foreignObject, like so:

<svg className="svg" viewBox="0 0 100 100">
 <path
  id="circle"
  d="M 50,50 m -40,0 a 40,40 0 1,0 80,0 a 40,40 0 1,0 -80,0"
  fill="transparent"
   />
  <text width="100px" height="100px">
  <textPath id="text" className="textPath" href="#circle">
   <foreignObject
    x="0"
    y="0"
    width="100"
    height="100"
    id="text"
    className="textPath"
    href="#circle"
    xmlns="http://www.w3.org/1999/xhtml"
    dangerouslySetInnerHTML={{
     __html: `<p>Made with <span role="img" aria-label="love">❤️</span> since 2023</p>`,
     }}
    />
   </textPath>
  </text>
</svg>

and, although I can see the html string is rendered just fine in the DOM. It is nowhere to be seen, as it seems that both <text>and <textPath>have no width or height. Am I missing something or is it simply not possible to use foreignObject in a textPath? Any other solutions much appreciated!


Solution

  • To display text in an SVG path, you can use the SVG tspan element instead of foreignObject. Smth like this:

    <svg className="svg" viewBox="0 0 100 100">
      <path
        id="circle"
        d="M 50,50 m -40,0 a 40,40 0 1,0 80,0 a 40,40 0 1,0 -80,0" 
        fill="transparent"
      />
      <text>
        <textPath id="text" className="textPath" href="#circle">
          <tspan x="0" dy="1em">Made with</tspan>
          <tspan x="0" dy="1em">❤️ since 2023</tspan>
        </textPath>
      </text>
    </svg>
    

    Attributes of tspan for fine-tuning are described here.