Reputation: 3414
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)
Upvotes: 222
Views: 460260
Reputation: 6187
You basically only need to support svg files on your react native project. Here I have created a custom component that would work just like regular react native image but added support for svg rendering.
import React from 'react';
import { Image, View } from 'react-native';
/**
* UniversalImage Component
* Supports both PNG/JPG (React Native Image) and SVG (React Component)
*/
const UniversalImage = ({ source, style, resizeMode, ...props }) => {
// Check if tintColor is provided in the style
const tintColor = style?.tintColor;
// Check if source is a function (svg) or just regular image source (png/jpg/..)
if (typeof source === 'function') {
// Source is an SVG Component
const SvgComponent = source;
// Apply the resizeMode logic to the SVG's container
const containerStyle = [style, { resizeMode: resizeMode || 'contain' }];
return (
<View style={containerStyle}>
<SvgComponent
width="100%" // always scale to 100% of the container
height="100%" // always scale to 100% of the container
preserveAspectRatio="xMidYMid meet" // always maintain aspect ratio
fill={style?.tintColor?? 'transparent'} // apply tintColor if provided
{...props} />
</View>
);
}
// Source is a PNG/JPG, apply resizeMode
return <Image source={source} style={[style, { resizeMode: resizeMode || 'contain' }]} {...props} />;
};
export default UniversalImage;
and use it just like your regular Image component, and for SVG files:
<UniversalImage
source={require('../assets/images/icon.svg').default}
style={{...styles.icon, iconStyle}} />
My use case is that the icon changes color according to a flag, so I simply use the tintColor style to do that and it is handled by the custom component.
Dont forget to modify your project to accept svg files. Install react-native-svg-transformer
and in your metro.config.js:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const defaultConfig = getDefaultConfig(__dirname);
// Modify resolver to support SVG files
defaultConfig.resolver.assetExts = defaultConfig.resolver.assetExts.filter(ext => ext !== 'svg');
defaultConfig.resolver.sourceExts.push('svg');
// Use `react-native-svg-transformer` for SVG files
defaultConfig.transformer.babelTransformerPath = require.resolve('react-native-svg-transformer');
module.exports = mergeConfig(defaultConfig, {});
Upvotes: 0
Reputation: 1
const SvgRenderer = ({ base64Svg, width = 50, height = 50 }) => {
try {
// Decode the Base64-encoded SVG string
let svgXml = decodeURIComponent(
atob(base64Svg.replace(/^data:image\/svg\+xml;base64,/, ''))
);
// Inline CSS styles into the SVG elements
svgXml = svgXml
.replace(/class="cls-1"/g, 'style="fill: none;"')
.replace(/class="cls-2"/g, 'style="fill: #004195;"');
console.log('Updated svgXml', svgXml);
return <SvgXml xml={svgXml} width={width} height={height} />;
} catch (error) {
console.error('Error parsing SVG:', error);
return null; // Render nothing if there's an error
}
};
Upvotes: 0
Reputation: 454
I wish I had this answer when I started wasting time on this, so for anyone still looking for the easiest way to display SVGs, it is using expo-image (https://docs.expo.dev/versions/latest/sdk/image/).
There are installation instructions for those who don't use expo, but for those who do, it's simply installing expo-image (npx expo install expo-image
) and using it in your code as follows.
It is working out of the box on Expo GO, and for those using Android/iOS build, you need to rebuild (obviously).
import { Image } from "expo-image";
import { View } from 'react-native';
export default function App() {
return (
<View>
<Image
source={require("../assets/some-image.svg")}
style={{ width: 32, height: 32 }}
/>
</View>
);
}
Upvotes: 2
Reputation: 314
You can use this way to show SVG data without convert
import { SvgXml } from "react-native-svg";
export type IconProps = Omit<XmlProps, 'xml'>
export function IconShare(props: IconProps) {
const xml = `
<svg width="17" height="20" viewBox="0 0 17 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.35303 13.0903C7.82178 13.0903 7.39844 12.6504 7.39844 12.144V4.05908L7.47314 2.83887L7.0415 3.48633L6.03711 4.54883C5.87939 4.73145 5.64697 4.82275 5.41455 4.82275C4.97461 4.82275 4.58447 4.49902 4.58447 4.02588C4.58447 3.78516 4.67578 3.61084 4.8418 3.44482L7.59766 0.796875C7.84668 0.547852 8.0957 0.456543 8.35303 0.456543C8.61035 0.456543 8.85938 0.547852 9.1167 0.796875L11.8643 3.44482C12.0303 3.61084 12.1216 3.78516 12.1216 4.02588C12.1216 4.49902 11.7314 4.82275 11.2915 4.82275C11.0508 4.82275 10.8267 4.73145 10.6689 4.54883L9.66455 3.48633L9.23291 2.84717L9.31592 4.05908V12.144C9.31592 12.6504 8.89258 13.0903 8.35303 13.0903ZM3.54688 19.9136C1.6543 19.9136 0.616699 18.8843 0.616699 17V9.02295C0.616699 7.13867 1.6543 6.11768 3.54688 6.11768H5.79639V8.25928H3.7793C3.11523 8.25928 2.7583 8.58301 2.7583 9.28857V16.7344C2.7583 17.4399 3.11523 17.7637 3.7793 17.7637H12.9268C13.5908 17.7637 13.9478 17.4399 13.9478 16.7344V9.28857C13.9478 8.58301 13.5908 8.25928 12.9268 8.25928H10.918V6.11768H13.1592C15.0601 6.11768 16.0894 7.14697 16.0894 9.02295V17C16.0894 18.876 15.0601 19.9136 13.1592 19.9136H3.54688Z" fill="currentColor"/>
</svg>
`
return <SvgXml {...props} xml={xml} />
}
Then you can add more properties for it like this:
<IconShare color="red" width={16} height={16} />
so you no need to convert your svg to React components by this way 😃
Upvotes: 1
Reputation: 472
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}/>
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}/>
)
Upvotes: -2
Reputation: 9
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
Upvotes: 0
Reputation: 455
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/
Upvotes: 0
Reputation: 4023
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"} />
Upvotes: -1
Reputation: 101
This following steps worked for me;
I renamed my svg to .js e.g: from logo.svg to logo.js
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>
imported logo from assets folder
import logo from '../../assets/logo';
install react-native-svg
import { SvgXml } from 'react-native-svg';
render logo within SvgXml
e.g: <SvgXml xml={logo} width={100} height={100} />
Upvotes: 1
Reputation: 181
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>
Upvotes: 0
Reputation: 627
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>
)
}
...
Upvotes: 4
Reputation:
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
Upvotes: 2
Reputation: 159
Incase anyone is stuck on this bug in 2022, here's the solution that worked for me:
Install react-native-svg-transformer:
yarn add react-native-svg-transformer --dev
or using npm
npm install react-native-svg-transformer --save-dev
Install react-native-svg:
yarn add react-native-svg
or using npm
npm install react-native-svg --save
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"]
}};
})();
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>
)
}
Upvotes: 0
Reputation: 622
You can try Converting .svg image to JSX with https://svg2jsx.herokuapp.com/
import open from "../../../../assets/SVGFile";
<SvgXml xml={open} scaleX={2} scaleY={2} width={20} height={20} />
Make sure to install, yarn add react-native-svg
All the best!
Upvotes: 0
Reputation: 1137
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:
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
Install babel-plugin-inline-import
by running yarn add babel-plugin-inline-import --dev
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']
}
};
})();
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 />
.
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.
Upvotes: 17
Reputation: 4905
I used the following solution:
.svg
image to JSX with https://svg2jsx.herokuapp.com/react-native-svg
component with https://react-svgr.com/playground/?native=true (make sure the "React Native" checkbox is checked)Upvotes: 162
Reputation: 945
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"
Upvotes: -2
Reputation: 8560
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}
/>
);
Upvotes: 28
Reputation: 479
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>
)
Upvotes: 10
Reputation: 3004
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>
Upvotes: 2
Reputation: 393
react-native-svg
to your project.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
Upvotes: 0
Reputation: 161
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"]
}
};
})();
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%"/>
Upvotes: 16
Reputation: 474
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
}
});
Upvotes: 4
Reputation: 1817
you can convert any SVG to a component and make it reusable.
here is my answer for the easiest way you can do it
Upvotes: 3
Reputation: 949
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
Upvotes: 0
Reputation: 4175
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" />
);
}
Upvotes: 20
Reputation: 626
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>
Upvotes: 37
Reputation: 1690
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 ✅
Upvotes: 4
Reputation: 2357
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')} />
Upvotes: 0
Reputation: 3708
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.
Upvotes: 13