SVG on web and mobile

Hi guys,

Does anyone find a solution using .svg on the web and mobile?
Appreciate any help.

Thanks.

Please could you elaborate on what you are trying to do, what you have tried, what you expect to happen and what happens instead?

Svg works fine on web and mobile if it’s inline, but I suspect you’re not using it like that?

1 Like

I use react-native-svg. Works well on iOS, Android.

import { SvgXml } from 'react-native-svg'
import svgIcon from '../assets/images/icon.svg'

<SvgXml width="40" height="40" xml={svgIcon} />

babel.config.js

module.exports = function(api) {
  api.cache(true);

  return {
    presets: [ 'babel-preset-expo', 'module:metro-react-native-babel-preset' ],
    plugins: [
      [ 'babel-plugin-inline-import', {
        extensions: [
          ".svg"
        ]
      }]
    ]
  };
};

So, I’m trying two options here for the web.

  1. No errors and image :slight_smile: , img tag does not render on DOM
import svgIcon from '../assets/images/icon.svg'

<Image source={svgIcon} />                                   
  1. React.createElement: type is invalid – expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it’s defined in, or you might have mixed up default and named imports.
import { SvgXml } from 'react-native-svg'
import svgIcon from '../assets/images/icon.svg'

<SvgXml width="40" height="40" xml={svgIcon} />                                 

OK, I think I know what the problem is.

You’re configuring metro to be able to import blah from 'something.svg'; which works for Android and iOS, but Expo for Web does not use metro as the bundler. It uses webpack instead.

So you will either need to figure out how to get webpack to do the same thing as metro is configured to do wrt. SVGs, or you’ll need to find a different approach. If you want to try the former, see the Customizing Webpack documentation. I see the react-native-svg-transformer documentation have an example that supposedly works on the web, so that seems like a good place to look too.

If you only have one or two icons that you want to use it might be easier to manually convert them to JSX to be used inline. This is mostly just capitalizing all the tags, but you might need to get rid of extra rubbish added by SVG-editing software like Inkscape. Inkscape has an option to save as an Optimized SVG which should help to get rid of most of the unnecessary stuff.

1 Like

To add to this great answer, https://react-svgr.com/playground/?native=true works pretty well too.

2 Likes

import Svg from "react-native-svg"; works perfect.
Thanks!

1 Like