title: SVG <use> element doesn't work on iOS or Safari in dynamic environment
body: <p>I can't get svg <code>&lt;use&gt;</code> elements to work on iOS in any browser. It also doesn't work on Safari on Mac. It does work on Android and in every other browser that I've tested on PC or Mac. In other words, it is probably a webkit problem. The environment is React when a <code>&lt;path&gt;</code> className is updated dynamically based upon system/user inputs and changes. This <code>&lt;path&gt;</code> element is hidden using viewBox and is referenced by a <code>&lt;use&gt;</code> element in a large svg element. This is the HTML produced by the React jsx:</p>
  <pre><code>&lt;form
     &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; version=&quot;1.1&quot; width=&quot;0&quot; height=&quot;0&quot; viewBox=&quot;0 0 0 0&quot;&gt;
     ...
        &lt;path id=&quot;path9146scheduleamap&quot; name=&quot;path9146scheduleamap&quot; d=&quot;m 146.86174,202.08294 v -13.04313 h 19.67563 v 13.04313 z m 0,0&quot; class=&quot;alert00During&quot;&gt;&lt;/path&gt;
     ...
     &lt;/svg&gt;
     &lt;div class=&quot;container-fluid&quot;&gt;
        &lt;div class=&quot;row&quot;&gt;
           &lt;div class=&quot;col&quot;&gt;
              &lt;svg xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:cc=&quot;http://creativecommons.org/ns#&quot; xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot; xmlns:svg=&quot;http://www.w3.org/2000/svg&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; id=&quot;mapSVG&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 199.58284 125.05578&quot; preserveAspectRatio=&quot;xMinYMin meet&quot; xmlns:svgjs=&quot;http://svgjs.dev/svgjs&quot; width=&quot;100%&quot; class=&quot;mapSVGClass&quot; style=&quot;cursor: move; user-select: none; touch-action: none; transform-origin: 50% 50%; transition: none 0s ease 0s; transform: scale(0.67032) translate(-107.635px, -394.821px);&quot;&gt;
                 ...
                 &lt;use id=&quot;use_path9146scheduleamap&quot; href=&quot;#path9146scheduleamap&quot; xlink:href=&quot;#path9146scheduleamap&quot; d=&quot;m 146.86174,202.08294 v -13.04313 h 19.67563 v 13.04313 z m 0,0&quot; transform=&quot;matrix(1,0,0,1,-8.574823231476401,-100.56069682128418)&quot;&gt;&lt;/use&gt;
                 ...
              &lt;/svg&gt;
           &lt;/div&gt;
        &lt;/div&gt;
     &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  <p>Here is the React code that updates the svg path elements.</p>
  <pre><code>class Venues extends Component{
     ...
     map2Venues(venue){
        return (
           &lt;path
             id={venue.mapIdentifier} 
             name={venue.mapIdentifier} 
             key={venue.mapIdentifier}
             d={venue.pathD}
             className={venue.alertClass}
           /&gt;
        );
     }
     ...
     render() {
        ...
        return (
           &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; version=&quot;1.1&quot; width=&quot;0&quot; height=&quot;0&quot; viewBox=&quot;0 0 0 0&quot; &gt;
              {this.reducedVenues.map((venue) =&gt; this.map2Venues(venue))}
           &lt;/svg&gt;
        );
        ...
     }
  }
  </code></pre>
  <p>Here is the React for the svg element with the <code>&lt;use&gt;</code> element:</p>
  <pre><code>class Map extends Component {
     ...
     render() {
        ...
        return (
          &lt;Container fluid&gt;
            &lt;Row&gt;
              &lt;Col&gt;
                &lt;div
                  id=&quot;svgMapDiv&quot;
                  ref={this.svgDivRef}
                  dangerouslySetInnerHTML={{ __html: this.props.svgMap }}
                /&gt;
              &lt;/Col&gt;
            &lt;/Row&gt;
          &lt;/Container&gt;
        );
        ...
     }
  }
  </code></pre>
  <p>The svg with the <code>&lt;use&gt;</code> element is only loaded once on component creation while the class attribute in the svg with <code>&lt;path&gt;</code> elements are updated frequently. I understand the danger associated with the inline svg. It is controlled. If it is a bug with webkit, a workaround solution for React would be appreciated.</p>
  <p><strong>UPDATE</strong>
  I confirmed in Safari on MacOS that when the <code>&lt;path&gt;</code> elements and corresponding attributes are statically applied and exist before the referencing <code>&lt;use&gt;</code> elements are created, the attributes are propagated to the <code>&lt;use&gt;</code> elements properly. More proof the problem is the <code>&lt;use&gt;</code> elements aren't updating when the <code>&lt;path&gt;</code> elements are updated dynamically.</p>
  <p>I found this <a href="https://bugs.webkit.org/show_bug.cgi?id=111927" rel="nofollow noreferrer">bug description</a> which doesn't seem to be resolved. I tried the work around described by Stuart P. Bentley on 2013-03-09 14:34:36 in that bug description, but it still does not work. That is, when attributes are changed directly and not by class or style attributes (a real pain), it still does not work on all iOS browsers and Safari on MacOS (but does work on all the other browsers and os). For example, changing the React code for the Venues component above still does not work:</p>
  <pre><code>class Venues extends Component{
     ...
     map2Venues(venue){
      let fill = &quot;&quot;;
      let stroke = &quot;&quot;;
      let stroke_width = &quot;&quot;;
      let animation_name = &quot;&quot;;
      let animation_duration = &quot;&quot;;
      let animation_iteration_count = &quot;&quot;;
      if(venue.alertClass.includes(&quot;alertSelected&quot;)){
        fill = &quot;purple&quot;;
        stroke = &quot;purple&quot;;
        stroke_width = &quot;1&quot;;
      }else if(venue.alertClass.includes(&quot;alert00During&quot;)){
        fill = &quot;green&quot;;
        stroke = &quot;green&quot;;
        stroke_width = &quot;1&quot;;
      }
      ...
      return (
        &lt;path
          id={venue.mapIdentifier} 
          name={venue.mapIdentifier} 
          key={venue.mapIdentifier}
          d={venue.pathD}
          opacity=&quot;0.8&quot;
          fill={fill}
          stroke={stroke}
          stroke-width={stroke_width}
        /&gt;
      );
    }
    ...
    render() {
       ...
       return (
          &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; version=&quot;1.1&quot; width=&quot;0&quot; height=&quot;0&quot; viewBox=&quot;0 0 0 0&quot; &gt;
             {this.reducedVenues.map((venue) =&gt; this.map2Venues(venue))}
          &lt;/svg&gt;
        );
        ...
    }
  }
  </code></pre>
  <p>Therefore, I still need a workaround to this bug because it doesn't seem to be being addressed. (Isn't this an important capability to have especially since all the other browsers and platforms support it?)</p>