213

I want to show svg files (I have bunch of svg images) but the thing I couldn't find the way to show. I tried to use Image and Use components of react-native-svg but they don't work with that. And I tried to do that with native way but it's really hard work to show just svg image.

Example code:

import Svg, {
  Use,
  Image,
} from 'react-native-svg';

<View>
  <Svg width="80" height="80">
     <Image href={require('./svg/1f604.svg')} />
  </SvgRn>
</View>

Also I know the react native doesn't support svg basically but I think someone fixed this problem with tricky way (with/without react-native-svg)

7
  • You can't use use to display an entire file, you'd need image for that. Commented Aug 8, 2016 at 13:55
  • Yeah i tried it too @RobertLongson but it doesn't work either. Commented Aug 8, 2016 at 13:57
  • You can add it as css backgroundImage, did you tried it? Commented Aug 8, 2016 at 14:01
  • I tried but react native View component doesn't support backgroundImage prop on css style. @danielarend Commented Aug 8, 2016 at 14:08
  • I'm not sure why you'd use an SVG wrapper to wrap an SVG image. Commented Aug 8, 2016 at 14:08

27 Answers 27

157

I used the following solution:

  1. Convert .svg image to JSX with https://svg2jsx.herokuapp.com/
  2. Convert the JSX to react-native-svg component with https://react-svgr.com/playground/?native=true (make sure the "React Native" checkbox is checked)
20
  • 2
    How to use that Component then? Can you share a code? Commented Oct 23, 2018 at 11:03
  • 3
    @IhorBurlachenko when I tired your solution, i got this error Uncaught Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function but got: object. could you help me here? Commented Nov 8, 2018 at 11:03
  • 3
    Anybody who has issue using this approach, please make sure that you do install the latest version of react-native-svg package. Also make sure to run this command to link your package react-native link react-native-svg Commented Apr 17, 2019 at 20:26
  • 3
    This is a long process to implement SVG files, better use github.com/kristerkari/react-native-svg-transformer as suggested below stackoverflow.com/a/55604442/1854104
    – hefgi
    Commented Aug 14, 2019 at 9:08
  • 3
    This is such a nightmare to do when you have hundreds of icons from your design.
    – ICW
    Commented Nov 15, 2021 at 20:06
30

Install react-native-svg-transformer

npm i react-native-svg-transformer --save-dev

I'm using SVG as following and it works fine

import LOGOSVG from "assets/svg/logo.svg"

in render

<View>
  <LOGOSVG 
    width="100%"
    height="70%"
  />
</View>
1
  • When i am importing svg file HEARTSVG from image folder then it showing error. And no error to import png files. Any suggestion?
    – Rakesh
    Commented Oct 27, 2020 at 14:13
26

I posted another solution (react-native-vector-icons) here. This approach use a vector font (from SVG) instead a SVG file. PS: react-native-vector-icons is the best approach to deal with SVG in react-native, it's also works in iOS and android. You will be able to change the color and size of your vector icon.

If you want to insert a svg directly into your app, you can try a 3rd party library : react-native-svg. With more than 3k stars in github it's one of the best approach.

Install any one of these using npm:

Then link it to native using

react-native link react-native-svg

An example with react-native-svg-uri:

import * as React from 'react';
import SvgUri from 'react-native-svg-uri'; // SVG Package
import testSvg from './test.svg';          // SVG File

export default () => (
  <SvgUri
    width="200"
    height="200"
    svgXmlData={testSvg}
  />
);
9
  • It gives an error "cannot add a child that doesn t have a css node to a node without a measure function". Commented Jan 31, 2018 at 9:15
  • 1
    Look the answer I post here, using a font instead a svg. it's a better solution: stackoverflow.com/questions/49951885/… Commented Apr 21, 2018 at 3:25
  • 5
    This library is so slow. It wraps every svg in its own webview.
    – JP_
    Commented Jan 4, 2019 at 2:46
  • 2
    tnx, this was quickest solution, but instead of svgXmlData={testSvg} i used source={testSvg} worked like a charm. tnx again. Commented May 6, 2020 at 9:06
  • 1
    @Omarbakhsh I would recommend you to try this stackoverflow.com/questions/49951885/… Commented Aug 13, 2020 at 12:01
19

I've tried all the above solutions and other solutions outside of the stack and none of working for me. finally, after long research, I've found one solution for my expo project.

If you need it to work in expo, one workaround might be to use https://react-svgr.com/playground/ and move the spreading of props to a G element instead of the SVG root like this:

import * as React from 'react';
import Svg, { G, Path } from 'react-native-svg';

function SvgComponent(props) {
  return (
    <Svg viewBox="0 0 511 511">
      <G {...props}>
        <Path d="M131.5 96c-11.537 0-21.955 8.129-29.336 22.891C95.61 132 92 149.263 92 167.5s3.61 35.5 10.164 48.609C109.545 230.871 119.964 239 131.5 239s21.955-8.129 29.336-22.891C167.39 203 171 185.737 171 167.5s-3.61-35.5-10.164-48.609C153.455 104.129 143.037 96 131.5 96zm15.92 113.401C142.78 218.679 136.978 224 131.5 224s-11.28-5.321-15.919-14.599C110.048 198.334 107 183.453 107 167.5s3.047-30.834 8.581-41.901C120.22 116.321 126.022 111 131.5 111s11.28 5.321 15.919 14.599C152.953 136.666 156 151.547 156 167.5s-3.047 30.834-8.58 41.901z" />
        <Path d="M474.852 158.011c-1.263-40.427-10.58-78.216-26.555-107.262C430.298 18.023 405.865 0 379.5 0h-248c-26.365 0-50.798 18.023-68.797 50.749C45.484 82.057 36 123.52 36 167.5s9.483 85.443 26.703 116.751C80.702 316.977 105.135 335 131.5 335a57.57 57.57 0 005.867-.312 7.51 7.51 0 002.133.312h48a7.5 7.5 0 000-15h-16c10.686-8.524 20.436-20.547 28.797-35.749 4.423-8.041 8.331-16.756 11.703-26.007V503.5a7.501 7.501 0 0011.569 6.3l20.704-13.373 20.716 13.374a7.498 7.498 0 008.134 0l20.729-13.376 20.729 13.376a7.49 7.49 0 004.066 1.198c1.416 0 2.832-.4 4.07-1.2l20.699-13.372 20.726 13.374a7.5 7.5 0 008.133 0l20.732-13.377 20.738 13.377a7.5 7.5 0 008.126.003l20.783-13.385 20.783 13.385a7.5 7.5 0 0011.561-6.305v-344a7.377 7.377 0 00-.146-1.488zM187.154 277.023C171.911 304.737 152.146 320 131.5 320s-40.411-15.263-55.654-42.977C59.824 247.891 51 208.995 51 167.5s8.824-80.391 24.846-109.523C91.09 30.263 110.854 15 131.5 15s40.411 15.263 55.654 42.977C203.176 87.109 212 126.005 212 167.5s-8.824 80.391-24.846 109.523zm259.563 204.171a7.5 7.5 0 00-8.122 0l-20.78 13.383-20.742-13.38a7.5 7.5 0 00-8.131 0l-20.732 13.376-20.729-13.376a7.497 7.497 0 00-8.136.002l-20.699 13.373-20.727-13.375a7.498 7.498 0 00-8.133 0l-20.728 13.375-20.718-13.375a7.499 7.499 0 00-8.137.001L227 489.728V271h8.5a7.5 7.5 0 000-15H227v-96.5c0-.521-.054-1.03-.155-1.521-1.267-40.416-10.577-78.192-26.548-107.231C191.936 35.547 182.186 23.524 171.5 15h208c20.646 0 40.411 15.263 55.654 42.977C451.176 87.109 460 126.005 460 167.5V256h-.5a7.5 7.5 0 000 15h.5v218.749l-13.283-8.555z" />
        <Path d="M283.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15zM331.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15zM379.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15zM427.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15z" />
      </G>
    </Svg>
  );
}

export default function App() {
  return (
    <SvgComponent width="100%" height="100%" strokeWidth={5} stroke="black" />
  );
}
2
  • 2
    This is also working fine for me. We can easily get the path of svg file by opening it on browser & view page source and then directly use the path & replace <path /> tag with react-native-svg <Path />. BIG THANKS
    – Rakesh
    Commented Oct 27, 2020 at 14:11
  • I had to set width & height to the wrapping View, otherwise the easiest and most straightforward way since you basically use your regular <svg> and just replace tags with the ones from react-native-svg as @Rakesh said right!
    – jave.web
    Commented Mar 6, 2022 at 17:56
16

Method that is working for me in 2022 for anyone that is still stuck on this, react native version 0.63.4, react-native-svg version ^12.1.0, you may be able to use this method for other versions too but always check the docs for the library first:

  1. Install react-native-svg-transformer by running this command yarn add react-native-svg-transformer --dev or using npm if you prefer npm i react-native-svg react-native-svg-transformer --save-dev

  2. Install babel-plugin-inline-import by running yarn add babel-plugin-inline-import --dev

  3. You need to update your metro.config.js file to looks like this:

const { getDefaultConfig } = require('metro-config');

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
      getTransformOptions: async () => ({
        transform: {
          experimentalImportSupport: false,
          inlineRequires: false
        }
      })
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg']
    }
  };
})();

  1. Make sure to import your svg file into your component like this: import CreditCard from '../assets/CreditCard'; please note how I am not adding the .svg file extension to the import, this is because it was giving me this error view config getter callback react-native-svg while running it but removing it seems to make it run smoothly. You can add your file this way as a jsx element like that <CreditCard />.

  2. Finally Restart your packager by stopping it using ^Ctrl + C on mac then restart it again with this command yarn start:dev --reset-cache and install the app again.

13

you can do this using a simple way

first, you should take installation,

  1. npm install -s react-native-svg
  2. react-native link react-native-svg
  3. npm install -s react-native-svg-transformer

then, you should add the following code in your metro.config.js file

const { getDefaultConfig } = require("metro-config");
module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer")
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"]
    }
  };
})();

after that, you should create a new file in your root directory with the name of declarations.d.js with the following code

declare module "*.svg" {
  import { SvgProps } from "react-native-svg";
  const content: React.FC<SvgProps>;
  export default content;
}

Finally, This is a import mathod

import USER from "../../assets/icons/user.svg"

and, this is for jsx

<USER width="100%" height="100%"/>

1
  • Can you make the font bigger please its too small
    – Rolf
    Commented Apr 22 at 18:28
12

After trying many ways and libraries I decided to create a new font (with Glyphs or this tutorial) and add my SVG files to it, then use "Text" component with my custom font.

Hope this helps anyone that has the same problem with SVG in react-native.

4
  • I think you are right, a font family is probably the easiest way to get simple svgs into react native
    – Joe Lloyd
    Commented Nov 24, 2017 at 7:57
  • Nice tutorial on that subject: blog.bam.tech/developper-news/…. Requires the Vector Icons Node package. Commented Feb 13, 2018 at 23:18
  • 1
    This solution isn't valid if you need to import multi-color sag file
    – Joe Aspara
    Commented Apr 15, 2018 at 22:33
  • 1
    I have tried its solution with icomoon and it didn't work out neither their support are active. And fontello is altering my svgs.
    – Siraj Alam
    Commented Sep 27, 2018 at 17:16
9

SVG does not support directly in Native applications. For displaying those we need to take help of third party modules

Please follow these steps

step 1. Install react-native-svg and react-native-svg-transformer

npm i react-native-svg react-native-svg-transformer

step 2. Add file metro.config.js if it doesn't exist

const { getDefaultConfig } = require("metro-config");

module.exports = (async () => { 
    const {  
        resolver: { 
            sourceExts, 
            assetExts 
        }  
    } = await getDefaultConfig(); 

    return {
        transformer: {      
            babelTransformerPath: require.resolve("react-native-svg-transformer")    
        },    
        resolver: {
            assetExts: assetExts.filter(ext => ext !== "svg"),
            sourceExts: [...sourceExts, "svg"]    
        }};
})();

step 3. Use SVG file like a React component

import Invest from '../assets/invest.svg'; // import SVG

return (
        <View>
            <Invest /> // Use SVG as component
        </View>
    )
1
  • 1
    Great what you share but i realize that react-native-svg-transformer have to be install as dev dependencies so like you install : First: yarn add react-native-svg or npm i --save react-native-svg and then: yarn add react-native-svg-transformer -D or npm i --dev react-native-svg-transformer.
    – Micessien
    Commented Jul 21, 2021 at 18:03
4

I had the same problem. I'm using this solution I found: React Native display SVG from a file

It's not perfect, and i'm revisiting today, because it performs a lot worse on Android.

2
  • Actually it's creative answer but it doesn't help my fits :) Because i will use icon list (10 or more SVG icons) so if i use this, it can be really bad for performance i guess. What do you think? Commented Aug 15, 2016 at 14:49
  • I rendered 10-15 svgs on a page. Nobody complained on iOS, everyone complained on Android. On iOS there is a 0.1-0.3 second delay (a split second flash of white before it loads). On Android it can be 1 second, and sometimes they never load. In the end I checked in my SVGs, then wrote a script which converts them to PNGs of exactly the correct size using svg2png. Then used <Image> with those PNGs. Given the current state of SVG in react native, there is no ETA for SVGs working, so this is your best bet if you can't tolerate the work around. Commented Aug 18, 2016 at 9:43
4

Use https://github.com/kristerkari/react-native-svg-transformer

In this package it is mentioned that .svg files are not supported in React Native v0.57 and lower so use .svgx extension for svg files.

For web or react-native-web use https://www.npmjs.com/package/@svgr/webpack


To render svg files using react-native-svg-uri with react-native version 0.57 and lower, you need to add following files to your root project

Note: change extension svg to svgx

step 1: add file transformer.js to project's root

// file: transformer.js

const cleanupSvg = require('./cleanup-svg');

const upstreamTransformer = require("metro/src/transformer");

// const typescriptTransformer = require("react-native-typescript-transformer");
// const typescriptExtensions = ["ts", "tsx"];

const svgExtensions = ["svgx"]

// function cleanUpSvg(text) {
//   text = text.replace(/width="([#0-9]+)px"/gi, "");
//    text = text.replace(/height="([#0-9]+)px"/gi, "");
//    return text;
// }

function fixRenderingBugs(content) {
  // content = cleanUpSvg(content); // cleanupSvg removes width and height attributes from svg
  return "module.exports = `" + content + "`";
}


module.exports.transform = function ({ src, filename, options }) {
  // if (typescriptExtensions.some(ext => filename.endsWith("." + ext))) {
  //  return typescriptTransformer.transform({ src, filename, options })
  // }

  if (svgExtensions.some(ext => filename.endsWith("." + ext))) {
    return upstreamTransformer.transform({
      src: fixRenderingBugs(src),
      filename,
      options
    })
  }

  return upstreamTransformer.transform({ src, filename, options });
}

step 2: add rn-cli.config.js to project's root

module.exports = {
    getTransformModulePath() {
      return require.resolve("./transformer");
    },
    getSourceExts() {
      return [/* "ts", "tsx", */ "svgx"];
    }
  };

The above mentioned solutions will work in production apps too ✅

0
3

you can convert any SVG to a component and make it reusable.

here is my answer for the easiest way you can do it

SVG to component

3
import React from 'react'
import SvgUri from 'react-native-svg-uri';

export default function Splash() {
  return (
    <View style={styles.container}>
      {/* provided the svg file is stored locally */}
      <SvgUri
        width="400"
        height="200"
        source={require('./logo.svg')}
      />
      {/* if the svg is online */}
      <SvgUri
        width="200"
        height="200"
        source={{ uri: 'http://thenewcode.com/assets/images/thumbnails/homer-simpson.svg' }}
      />

      <Text style={styles.logoText}>
        Text
      </Text>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  logoText: {
    fontSize: 50
  }
});
1
  • use npm install react-native-svg-uri --save to install the needed package Commented Nov 1, 2020 at 20:46
3

Using svg in a react native project is not as simple as using it in the web, although it is not that difficult either.

Many of the above answers are complicated in my view. So, here is the solution that I use and like.

Since react native does not support the svg file format directly you need to follow some steps to get it working.

1. Install react-native-svg

 npm install react-native-svg --save

This package will help you render the svg file

2. Install react-native-svg-transformer

npm install react-native-svg-transformer --save 

This package will transform your svg to the format that react native understands.

3. Import the svg as normal component

import Belsvg from "../assets/belsvg.svg"; 

While importing give it a name that you like now this svg is transformed into a react native component by the react-native-svg-transformer

4. Now you can use this as a normal component

For a detailed explanation and example visit the link :

https://kumar2396jayant.medium.com/how-to-use-svg-in-react-native-e581eca59534

ps: I would like to thank Jayant kumar yadav for posting that blog

3

If you're using React Native with TypeScript, here is the step-by-step solution:

1. Install react-native-svg

npm install react-native-svg

or

yarn add react-native-svg

2. Link native code

cd ios && pod install

3. Install react-native-svg-transformer

npm install --save-dev react-native-svg-transformer

or

yarn add --dev react-native-svg-transformer

4. Configure the react native packager

For React Native v0.59 or newer:

Merge the contents from your project's metro.config.js file with this config (create the file if it does not exist already).

const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer")
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"]
    }
  };
})();

This is how my merged metro.config.js looks like:

const { getDefaultConfig } = require('metro-config')

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig()
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
      getTransformOptions: async () => ({
        transform: {
          experimentalImportSupport: false,
          inlineRequires: true,
        },
      }),
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  }
})()

5. TypeScript configuration:

If you are using TypeScript, you need to add this to your declarations.d.ts file (create one if you don't have one already):

declare module "*.svg" {
  import React from 'react';
  import { SvgProps } from "react-native-svg";
  const content: React.FC<SvgProps>;
  export default content;
}

6. Usage

...
import LogSvg from '../assets/images/Logo.svg'

export function LandingScreen(): JSX.Element {
  ...
  return (
    <View style={style.mainContainer}>
      <LogSvg style={style.logoContainer} />
    </View>
  )
}

...
2
1

I've written a new library to be able to use native vector assets based on .svg files called react-native-vector-image. It doesn't need any custom babel transforms and you can use it like you would for other bitmap based assets, but there is an extra step in transforming the svg to the native equivalents (you only need to run it when you add new assets though).

Using your example the code would look something like this

import VectorImage from 'react-native-vector-image';

<View>
  <VectorImage source={require('./svg/1f604.svg')} />
</View>
6
  • Can we send some extra props to the VectorImage component? Something like dynamic color for the element in the svg file? Commented May 13, 2021 at 8:44
  • You can set a tintColor prop.
    – oblador
    Commented May 14, 2021 at 9:04
  • But I guess tintColor will add color to the whole svg file. Commented May 14, 2021 at 9:18
  • 1
    Yeah, it’s a static image not a react component. You can provide a dark mode or high contrast version, but you are limited to what a static image file can do, so no logic. Maybe you can explain what you want to acheive?
    – oblador
    Commented May 15, 2021 at 10:42
  • 1
    That sounds like a job for react-native-svg.
    – oblador
    Commented May 16, 2021 at 10:57
1

I try to use SvgCssUri and it works

import {SvgCssUri} from 'react-native-svg/css';
...
...
...
<SvgCssUri 
style={{height: 100, width: 100}} 
uri={"http://thenewcode.com/assets/images/thumbnails/homer-simpson.svg"} />
0

Note: Svg does not work for android release versions so do not consider for android. It will work for android in debug mode only. But it works fine for ios.

Use https://github.com/vault-development/react-native-svg-uri

Install

npm install react-native-svg-uri --save
react-native link react-native-svg # not react-native-svg-uri

Usage

import SvgUri from 'react-native-svg-uri';


<SvgUri source={require('./path_to_image/image.svg')} />
1
  • @AravindVemula you are right. It does not work for android release versions. I also couldn't find a solution. Probably there is no solution till now. I abandoned using svg and turned back to the traditional way of react native images Commented Apr 4, 2019 at 11:54
0

I use these two plugins,

  1. [react-native-svg] https://github.com/react-native-community/react-native-svg)
  2. [ react-native-svg-transformer] https://github.com/kristerkari/react-native-svg-transformer)

First off all, You need to install that plugin. After that you need to change your metro.config.js, with this code.

const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer")
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"]
    }
  };
})();

For more details, you can visit this link

0
  1. First install react-native-svg to your project.
  2. Open https://react-svgr.com/ and go to the playground and select React native
  3. Copy paste your SVG code and used the output code.

Ex:- This is the sample SVG that I have got.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17" height="17" viewBox="0 0 17 17">
    <defs>
        <path id="a" d="M16.191 1.027L9.023 8.196l7.168 7.168-.83.83-7.169-7.167-7.168 7.168-.831-.831L7.36 8.196.19 1.027l.832-.83L8.19 7.366 15.359.197z"/>
    </defs>
    <g fill="none" fill-rule="evenodd">
        <mask id="b" fill="#fff">
            <use xlink:href="#a"/>
        </mask>
        <use fill="#FFF" fill-rule="nonzero" xlink:href="#a"/>
        <g fill="#3D3D3D" mask="url(#b)">
            <path d="M0 0h16v16H0z"/>
        </g>
    </g>
</svg>

Output:-

import * as React from "react"
import Svg, { Defs, Path, G, Mask, Use } from "react-native-svg"

function SvgComponent(props) {
  return (
    <Svg
      xmlns="http://www.w3.org/2000/svg"
      xmlnsXlink="http://www.w3.org/1999/xlink"
      width={17}
      height={17}
      viewBox="0 0 17 17"
      {...props}
    >
      <Defs>
        <Path
          id="prefix__a"
          d="M16.191 1.027L9.023 8.196l7.168 7.168-.83.83-7.169-7.167-7.168 7.168-.831-.831L7.36 8.196.19 1.027l.832-.83L8.19 7.366 15.359.197z"
        />
      </Defs>
      <G fill="none" fillRule="evenodd">
        <Mask id="prefix__b" fill="#fff">
          <Use xlinkHref="#prefix__a" />
        </Mask>
        <Use fill="#FFF" fillRule="nonzero" xlinkHref="#prefix__a" />
        <G fill="#3D3D3D" mask="url(#prefix__b)">
          <Path d="M0 0h16v16H0z" />
        </G>
      </G>
    </Svg>
  )
}

export default SvgComponent

** But when I use the above code in my project and it does not render properly. So I done it as below and somehow it works for me.

import * as React from "react"
import Svg, { Path, G } from "react-native-svg"

function SvgComponent(props) {
  return (
    <Svg
      width={17}
      height={17}
      {...props}
    >
        <G>
            <Path
                id="prefix__a"
                d="M16.191 1.027L9.023 8.196l7.168 7.168-.83.83-7.169-7.167-7.168 7.168-.831-.831L7.36 8.196.19 1.027l.832-.83L8.19 7.366 15.359.197z"
            />
        </G>
    </Svg>
  )
}

export default SvgComponent
0

You can try Converting .svg image to JSX with https://svg2jsx.herokuapp.com/

  • Then save the JSX code in assest/SVGFile.js
  • Then import it, for example import open from "../../../../assets/SVGFile";
  • Lastly add <SvgXml xml={open} scaleX={2} scaleY={2} width={20} height={20} />

Make sure to install, yarn add react-native-svg

All the best!

0

Incase anyone is stuck on this bug in 2022, here's the solution that worked for me:

  1. Install react-native-svg-transformer:
    yarn add react-native-svg-transformer --dev
    or using npm
    npm install react-native-svg-transformer --save-dev

  2. Install react-native-svg:
    yarn add react-native-svg
    or using npm
    npm install react-native-svg --save

  3. Update your metro.config.js file to looks like this:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');

module.exports = (() => { 
    const {  
        resolver: { 
            sourceExts, 
            assetExts 
        }  
    } = getDefaultConfig(__dirname); 

    return {
        transformer: {      
            babelTransformerPath: require.resolve("react-native-svg-transformer")    
        },    
        resolver: {
            assetExts: assetExts.filter(ext => ext !== "svg"),
            sourceExts: [...sourceExts, "svg"]    
        }};
})();
  1. Import and display the svg image in your code like below:
import {View} from 'react-native';
import SvgImage from './path/to/svg/file.svg';

function MyComponent(){
    return (
        <View>
          <SvgImage />
        </View>
    )
}
0

The best solution that worked for me on both platforms is https://github.com/seekshiva/react-native-remote-svg.

I additionally did a conditional render with https://github.com/react-native-svg/react-native-svg to have the best result on both platforms, because there's an know issue with Android as stated here https://stackoverflow.com/a/54182426/4934132.

Just in case I have ErrorBoundry to cover the exceptions.

It looks like this:

<ErrorBoundary
  FallbackComponent={error => ErrorFallback(error)}
  onReset={() => {
    // reset the state of your app so the error doesn't happen again
  }}
  onError={myErrorHandler}
>
  {Platform.OS === 'ios' ?
    <SvgCssUri width="100%" height="100%" uri={url} />
    :
    <Image
      source={{ uri: url }}
      style={{ width: "100%", height: '100%' }}
    />
  }
</ErrorBoundary>
0

This following steps worked for me;

  1. I renamed my svg to .js e.g: from logo.svg to logo.js

  2. added the keyword export default at the beginning of the svg content and wrapped all in template strings, e.g:
    // in logo.js
    export default <svg ... > ... </svg>

  3. imported logo from assets folder import logo from '../../assets/logo';

  4. install react-native-svg

  5. import { SvgXml } from 'react-native-svg';

  6. render logo within SvgXml e.g: <SvgXml xml={logo} width={100} height={100} />

0

A simple way to do that is to use react-native-skia which is a Shopify supported library here is an example code:

import React from "react";
import { Canvas, ImageSVG, Skia, rect, fitbox, useSVG, Group, Paint, OpacityMatrix, ColorMatrix } from "@shopify/react-native-skia";
 
const width = 256;
const height = 256;
 
export const SVG = () => {
  const tiger = useSVG(require("./tiger.svg"));
  if (!tiger) {
    return null;
  }
  const src = rect(0, 0, tiger.width(), tiger.height());
  const dst = rect(0, 0, width, height);
  return (
    <Canvas style={{ flex: 1 }}>
      <Group
        transform={fitbox("contain", src, dst)}
        layer={<Paint><ColorMatrix matrix={OpacityMatrix(0.5)} /></Paint>}
      >
        <ImageSVG svg={tiger} x={0} y={0} width={800} height={800} />
      </Group>
    </Canvas>
  );
};

For further information you can check the docs: https://shopify.github.io/react-native-skia/docs/images-svg/

0

Sometimes we encounter some unexpected issues with the implementation of SVGs but with this approach it reduces the error rate. If you want to modify your svg then you can also modify its react native component code.

first, install

yarn add react-native-svg

There is a simple way to use any type of SVG in react native. You can just convert the SVG code into react native and use it as a component. here is the link that converts svg into the React native.

https://transform.tools/svg-to-react-native

like here is svg code

<svg style="flex:1;" xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <rect x="10" y="10" height="100" width="100"
    style="stroke:#ff0000; fill: #0000ff"/>
</svg>

here is converted React native code which can b e use as component

import * as React from "react"
import Svg, { Path } from "react-native-svg"

function SvgComponent(props) {
  return (
    <Svg
      style={{
        flex: 1
      }}
      xmlns="http://www.w3.org/2000/svg"
      {...props}
    >
      <Path d="M10 10H110V110H10z" stroke="red" fill="#00f" />
    </Svg>
  )
}
export default SvgComponent
0

You can use LocalSvg from react-native-svg.

you don't have to install other packages to call local svg. just install react-native-svg.

import { LocalSvg } from 'react-native-svg/css';
<LocalSvg asset={require('../Assets/svg/seats.svg')} height={100} width={100}/>

Or,

npm install --save babel-plugin-inline-import

change your bable.config.js to this,

module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: [
    [
      'babel-plugin-inline-import',
      {
        extensions: ['.svg'],
      },
    ],
    'react-native-reanimated/plugin',
  ],
};

Then in your file,

import Svg, {Circle, Image, Text as SvgText, SvgXml} from 'react-native-svg';
import Seats from '../Assets/svg/seats.svg';

return(
      <LocalSvg asset={require('../Assets/svg/seats.svg')} height={100} width={100}/>
)
-2

Use react-native-svg see its supports both android and Ios.

this is the basic example

import * as React from 'react';
import { SvgUri } from 'react-native-svg';

export default () => (
  <SvgUri
    width="100%"
    height="100%"
    uri="http://thenewcode.com/assets/images/thumbnails/homer-simpson.svg"
  />
);

if you want to use both normal image and svg images in one component, You can make a custom function that checks if the url has svg and return Image component or SvgUri

        const ImageComponent = (Props) => {
            const {Istyle, url, mode} = props;
            const isSvg = url?.includes('.svg') ?? false;
        
            if (isSvg) {
              return <SvgCssUri style={Istyle} uri={defaultAvatar} />;
            }
            if (!isSvg) {
              return <Image style={Istyle} source={{uri: url}} resizeMode={mode} />;
            }
          };

//let testURl = "https://avatars.dicebear.com/api/male/john.svg"
1
  • Using an absolute URL in your code is a bad idea.
    – Rolf
    Commented Apr 22 at 18:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.