react-native-svg

repository·main·Indexed 27 days ago

https://github.com/software-mansion/react-native-svg

An SVG library for React Native that provides SVG support for iOS, Android, macOS, Windows, and the web. It allows developers to use standard SVG elements such as Rect, Circle, Line, and Path, and includes specialized components like SvgUri, SvgXml, and SvgCssUri for loading remote or string-based SVG content.

Tokens
16K
Snippets
40
Records
42
Agent score
93%

What's inside react-native-svg

  1. Use SVG Filters

    main

    SVG Filters allow you to process an element's rendering (e.g., blurring, color intensity, warping) before it is composited.

    Supported Filters (Native):

    • FeBlend
    • FeComposite
    • FeColorMatrix
    • FeDropShadow
    • FeFlood
    • FeGaussianBlur
    • FeMerge
    • FeOffset

    Note: Some filters may not be implemented on native platforms yet but will work on the Web. If a filter is unsupported on native, a warning will be displayed.

    To use a filter, define a <Filter> element with an id inside your <Svg> component, and then reference that ID in the filter prop of a target element using the url(#id) syntax.

    import React from 'react';
    import { FeColorMatrix, Filter, Rect, Svg } from 'react-native-svg';
    
    export default () => {
      return (
        <Svg height="300" width="300">
          <Filter id="myFilter">
            <FeColorMatrix type="saturate" values="0.2" />
          </Filter>
          <Rect
            x="0"
            y="0"
            width="300"
            height="300"
            fill="red"
            filter="url(#myFilter)"
          />
        </Svg>
      );
    };
  2. Install react-native-svg with react-native-cli

    main

    For standard React Native CLI projects, follow these two steps:

    1. Install the library via npm or yarn.
    2. Link the native code by installing pods in the iOS directory.
    # 1. Install library
    npm install react-native-svg
    # OR
    yarn add react-native-svg
    
    # 2. Link native code
    cd ios && pod install
  3. Use SVG files as components with react-native-svg-transformer

    main

    To import .svg files directly as React components, use react-native-svg-transformer. This requires updating your metro.config.js to treat .svg files as source extensions instead of assets.

    // metro.config.js for react-native >= 0.72
    const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
    
    const defaultConfig = getDefaultConfig(__dirname);
    const { assetExts, sourceExts } = defaultConfig.resolver;
    
    const config = {
      transformer: {
        babelTransformerPath: require.resolve('react-native-svg-transformer'),
      },
      resolver: {
        assetExts: assetExts.filter((ext) => ext !== 'svg'),
        sourceExts: [...sourceExts, 'svg'],
      },
    };
    
    module.exports = mergeConfig(defaultConfig, config);

    Then import and use the file:

    import Logo from './logo.svg';
    
    <Logo width={120} height={40} />
  4. Apply filters to images with FilterImage

    main

    The FilterImage component (imported from react-native-svg/filter-image) behaves like a standard React Native Image component but supports an additional filters prop or CSS-style filter property via the style prop to apply visual effects.

    Method 1: Using the filters prop

    Pass an array of filter objects to the filters prop. Each object should specify a name (e.g., 'feColorMatrix'), a type, and the corresponding values.

    Method 2: Using CSS API via style

    On Web, you can use the standard CSS filter string within the style prop (e.g., 'saturate(3) grayscale(100%)').

    import React from 'react';
    import { StyleSheet } from 'react-native';
    import { FilterImage } from 'react-native-svg/filter-image';
    
    const myImage = require('./myImage.jpg');
    
    export default () => {
      return (
        <FilterImage
          style={styles.image}
          source={myImage}
          filters={[
            { name: 'feColorMatrix', type: 'saturate', values: 0.2 },
            {
              name: 'feColorMatrix',
              type: 'matrix',
              values: [
                0.2, 0.2, 0.2, 0, 0, 0.2, 0.2, 0.2, 0, 0, 0.2, 0.2, 0.2, 0, 0, 0, 0,
                0, 1, 0,
              ],
            },
          ]}
        />
      );
    };
    
    const styles = StyleSheet.create({
      image: {
        width: 200,
        height: 200,
      },
    });
  5. Use currentColor for inherited styles

    main

    The color prop on an <Svg> element defines a color variable that can be inherited by its children. Children can access this value using the special keyword currentColor in any prop that accepts a color (e.g., fill="currentColor" or stroke="currentColor").

    <Svg
      width="130"
      height="130"
      fill="blue"
      stroke="red"
      color="green"
      viewBox="-16 -16 544 544">
      <Path
        d="M318.37,85.45L422.53,190.11,158.89,455,54.79,350.38ZM501.56,60.2L455.11,13.53a45.93,45.93,0,0,0-65.11,0L345.51,58.24,449.66,162.9l51.9-52.15A35.8,35.8,0,0,0,501.56,60.2ZM0.29,497.49a11.88,11.88,0,0,0,14.34,14.17l116.06-28.28L26.59,378.72Z"
        strokeWidth="32"
      />
      <Path d="M0,0L512,512" stroke="currentColor" strokeWidth="32" />
    </Svg>
  6. Configure Webpack for React Native Web

    main

    When using Webpack, you must install @react-native/assets-registry/registry and configure your module.rules to include it in the babelLoaderConfiguration.

    const babelLoaderConfiguration = {
     include: [
       path.resolve(
         appDirectory,
         // Important!
         'node_modules/@react-native/assets-registry/registry',
       ),
     ],
     ...
    };
    
    module.exports = {
     ...config,
     module: {
         rules: [babelLoaderConfiguration],
       },
    };
  7. Troubleshoot unexpected behavior

    main

    If you encounter unexpected behavior, create a clean reproduction project to isolate the issue:

    1. Initialize a new project: react-native init CleanProject.
    2. Install react-native-svg: yarn add react-native-svg.
    3. Install iOS pods: cd ios && pod install && cd ...
    4. Reproduce the issue in App.js and run on iOS/Android.
    react-native init CleanProject
    cd CleanProject/
    yarn add react-native-svg
    cd ios && pod install && cd ..
    
    react-native run-ios
    react-native run-android
  8. Embed non-SVG content with ForeignObject

    main

    The <ForeignObject> element allows you to include non-SVG XML elements (like React Native View, Text, or Image) within an SVG region. The included content is subject to SVG transformations, filters, clipping, masking, and compositing. You must specify x, y, width, and height for the ForeignObject.

    import React, { Component } from 'react';
    import { Text, View, Image } from 'react-native';
    import {
      Svg,
      Defs,
      LinearGradient,
      Stop,
      Mask,
      Rect,
      G,
      Circle,
      ForeignObject,
    } from 'react-native-svg';
    
    export default class App extends Component {
      render() {
        return (
          <View style={{ flex: 1, justifyContent: 'center' }}>
            <Svg height="50%">
              <Defs>
                <LinearGradient
                  id="Gradient"
                  gradientUnits="userSpaceOnUse"
                  x1="0"
                  y1="0"
                  x2="800"
                  y2="0">
                  <Stop offset="0" stopColor="white" stopOpacity="0.2" />
                  <Stop offset="1" stopColor="white" stopOpacity="1" />
                </LinearGradient>
                <Mask
                  id="Mask"
                  maskUnits="userSpaceOnUse"
                  x="0"
                  y="0"
                  width="800"
                  height="300">
                  <Rect
                    x="0"
                    y="0"
                    width="800"
                    height="300"
                    fill="url(#Gradient)"
                  />
                </Mask>
              </Defs>
              <G mask="url(#Mask)">
                <Circle cx={50} cy={70} r={65} />
                <ForeignObject x={50} y={0} width={100} height={100}>
                  <View style={{ width: 200, height: 400, transform: [] }}>
                    <Image
                      style={{ width: 200, height: 200 }}
                      source={{
                        uri: 'https://picsum.photos/200/200',
                      }}
                    />
                  </View>
                </ForeignObject>
                <ForeignObject x={55} y={5} width={100} height={100}>
                  <View style={{ width: 200, height: 400, transform: [] }}>
                    <Text style={{ color: 'blue' }}>Testing</Text>
                    <Text style={{ color: 'green' }}>Testing2</Text>
                  </View>
                </ForeignObject>
              </G>
            </Svg>
          </View>
        );
      }
    }
  9. Use Patterns to fill or stroke objects

    main

    Patterns allow you to fill or stroke an object using a pre-defined graphic object that is tiled at fixed intervals. To use a pattern:

    1. Define the <Pattern> element inside a <Defs> tag.
    2. Assign a unique id to the pattern.
    3. Reference the pattern in the fill or stroke property of a graphics element using the url(#id) syntax.
    <Svg width="100%" height="100%" viewBox="0 0 800 400">
      <Defs>
        <Pattern
          id="TrianglePattern"
          patternUnits="userSpaceOnUse"
          x="0"
          y="0"
          width="100"
          height="100"
          viewBox="0 0 10 10">
          <Path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" stroke="blue" />
        </Pattern>
      </Defs>
      <Rect fill="none" stroke="blue" x="1" y="1" width="798" height="398" />
      <Ellipse
        fill="url(#TrianglePattern)"
        stroke="black"
        strokeWidth="5"
        cx="400"
        cy="200"
        rx="350"
        ry="150"
      />
    </Svg>
  10. Use Markers for arrowheads and polymarkers

    main

    Markers are symbols attached to vertices of path, line, polyline, and polygon elements (e.g., for arrowheads).

    To use a marker:

    1. Define a <Marker> element inside <Defs> with an id.
    2. Use properties like markerStart, markerMid, or markerEnd on the target element to reference the marker via url(#id).

    Common marker properties include viewBox, refX, refY, markerUnits, markerWidth, markerHeight, and orient.

    <Svg width="400" height="200" viewBox="0 0 4000 2000">
      <Defs>
        <Marker
          id="Triangle"
          viewBox="0 0 10 10"
          refX="0"
          refY="5"
          markerUnits="strokeWidth"
          markerWidth="4"
          markerHeight="3"
          orient="auto">
          <Path d="M 0 0 L 10 5 L 0 10 z" />
        </Marker>
      </Defs>
      <Rect
        x="10"
        y="10"
        width="3980"
        height="1980"
        fill="none"
        stroke="blue"
        strokeWidth="10"
      />
      <Path
        d="M 1000 750 L 2000 750 L 2500 1250"
        fill="none"
        stroke="black"
        strokeWidth="100"
        markerEnd="url(#Triangle)"
      />
    </Svg>