'SVG sprite images not showing on iOS & Safari using React

I am trying to use my svg images with a sprite file. Importing sprite file in relevant component and using custom Svg component to render images with symbol id's. Svg image dimensions described in css classes. Everything works without any problems in Firefox and Chrome but mobile & desktop Safari does not rendering images. Based on suggestions, tried xmlns:xlink, width, height, viewBox attributes on svg tag. Nothing worked.

In source code I can see that SVG is present and it's taking space in page. But it's blank.

I appreciate any suggestions.

Here is my sprite file content:

<svg>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 5 8.586" id="icon-angle-left">
    <g>
      <g fill="none">
        <path d="M0 0H6.981V3.491H0z" transform="translate(0.472 0.707) translate(3.821 3) rotate(90) translate(-2.809 0.331)"></path>
        <path stroke="#555" stroke-linecap="round" d="M2577 1784.713l3.586 3.586 3.586-3.586" transform="translate(0.472 0.707) translate(3.821 3) rotate(90) translate(-2579.998 -1784.713)"></path>
      </g>
    </g>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 21" id="icon-home">
    <path fill="none" d="M0 0h21v21H0z"></path>
    <path fill="#555" d="M10.75 5.354l4.375 3.938v6.834h-1.75v-5.25h-5.25v5.25h-1.75V9.291l4.375-3.937m0-2.354L2 10.875h2.625v7h5.25v-5.25h1.75v5.25h5.25v-7H19.5z" transform="translate(-0.25 -0.375)"></path>
  </symbol>
</svg>

Here is my Svg component:

import React from 'react';
import './style.scss'; 

const Svg = ({ symbolId, className }) => {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" className={className}>
      <use xlinkHref={symbolId}></use>
    </svg>
  );
};

export default Svg;

And using it like this;

import React from 'react';
import sprite from 'sprites/product-list.svg';
import Svg from 'shared/Svg';

const MyComponent = () => {
  return (
    <div>
      <Svg className="image" symbolId={sprite + "#icon-home"} />
    </div>
  );
};

export default MyComponent;


Solution 1:[1]

It turns out that Safari does not support working with external svg files like this.

This is how we solved this situation:

Created a icons.jsx file that exports all the svg contents as a component. And used a prop for class name for further styling:

import React from 'react';

export const IconTick = ({ className }) => (
  <svg className={className} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16.662 12.505" id="icon-tick">
    <path d="M14.151.431L5.629 8.953 2.511 5.835a1.471 1.471 0 0 0-2.08 2.08l4.159 4.158a1.469 1.469 0 0 0 2.08 0l9.562-9.562a1.471 1.471 0 0 0-2.081-2.08z" />
  </svg>
);

export const IconTimes = ({ className }) => (
  <svg className={className} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" id="icon-times">
    <g id="Component_139_1" data-name="Component 139 – 1" transform="translate(1.414 1.414)">
      <path id="Path_866" data-name="Path 866" d="m46.167 46.5-6 6 6 6" transform="translate(-34.167 -46.5)" />
      <path id="Path_1015" data-name="Path 1015" d="m40.167 46.5 6 6-6 6" transform="translate(-40.167 -46.5)" />
    </g>
  </svg>
);

Created an alias in webpack.common.js for accessing svg's with a clean way:

module.exports = {
    ...
    resolve: {
        alias: {
            ...
            icons: path.resolve(__dirname, 'src/SharedComponents/Icons/'),
            ...
        },
        ...
    },
    ...
};

And just used them like:

import React from 'react';
import { IconAngleLeft, IconTick } from 'icons';

const MyOtherComponent = () => {
  return (
    <div className="some-div">
      <IconAngleLeft className={'foo'} />
      <IconTick className={'bar'} />
    </div>
  );
};

export default MyOtherComponent;

It works everywhere without any problems and it's very easy I think. But you may need to correct your svg contents for Jsx syntax.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Gökberk Konuralp