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)
This question is related to
javascript
svg
react-native
you can do this using a simple way
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"]
}
};
})();
_x000D_
declare module "*.svg" {
import { SvgProps } from "react-native-svg";
const content: React.FC<SvgProps>;
export default content;
}
_x000D_
Finally, This is a import mathod
import USER from "../../assets/icons/user.svg"
_x000D_
and, this is for jsx
<USER width="100%" height="100%"/>
_x000D_
you can convert any SVG to a component and make it reusable.
here is my answer for the easiest way you can do it
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.
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
tosvgx
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 });
}
rn-cli.config.js
to project's rootmodule.exports = {
getTransformModulePath() {
return require.resolve("./transformer");
},
getSourceExts() {
return [/* "ts", "tsx", */ "svgx"];
}
};
The above mentioned solutions will work in production apps too ?
All these solutions are absolutely horrid. Just convert your SVG to a PNG and use the vanilla <Image/>
component. The fact that react-native still does not support SVG images in the Image
component is a joke. You should never install an additional library for such a simple task. Use https://svgtopng.com/
I posted another solution here Which is the best approach to insert an vector (svg) graph into a react native application, This approach use a vector font(from svg) instead a svg file. PS: Its works great in ios and android, and you also can 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.
And here's a sample:
import * as React from 'react';
import SvgUri from 'react-native-svg-uri';
import testSvg from './test.svg';
export default () => (
<SvgUri
width="200"
height="200"
svgXmlData={testSvg}
/>
);
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')} />
I used the following solution:
.svg
image to JSX with https://svg2jsx.herokuapp.com/react-native-svg
component with https://svgr.now.sh/ (check the "React Native checkbox)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>
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" />
);
}
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
}
});
I use these two plugins,
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
Source: Stackoverflow.com