react-native-svg-transformer

repository·master·Indexed 23 days ago

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

An SVG transformer for react-native (v1.5.3) that allows developers to import .svg files directly as React components. It utilizes SVGR under the hood and provides configuration guides for Metro in Expo (SDK v41.0.0+) and React Native (v0.59, v0.72.1+), TypeScript declarations, Jest mocking, and custom SVGR transformation settings via .svgrrc.

Tokens
2K
Snippets
6
Records
13
Agent score
33%

What's inside react-native-svg-transformer

  1. Configure Jest to mock SVG imports

    master

    When running tests with Jest, you must mock .svg files to prevent errors.

    1. Create __mocks__/svgMock.js:
    module.exports = "SvgMock";
    1. Add the mock to your Jest configuration in package.json or jest.config.js using moduleNameMapper.
    {
      "jest": {
        "moduleNameMapper": {
          "\\.svg": "<rootDir>/__mocks__/svgMock.js"
        }
      }
    }
  2. Customize SVG transformation with SVGR

    master

    The transformer uses SVGR under the hood. You can customize how SVGs are transformed by creating a .svgrrc file in your project root.

    Replace attribute values

    To replace specific colors (e.g., red) with currentColor globally:

    {
      "replaceAttrValues": {
        "red": "currentColor"
      }
    }

    Enable dynamic fill via props

    To allow passing a fill prop from React code to the SVG, map a specific hex code in your SVG to {props.fill} in .svgrrc:

    1. In .svgrrc:
    {
      "replaceAttrValues": {
        "#000": "{props.fill}"
      }
    }
    1. In your .svg file:
    <path d="..." fill="#000"/>
    1. In your React component:
    <Logo fill="any color" />
  3. Configure Metro for React Native v0.59 or newer

    master

    For older React Native projects (v0.59+), use an asynchronous configuration in metro.config.js to merge the transformer and resolver settings.

    const { getDefaultConfig } = require("metro-config");
    
    module.exports = (async () => {
      const {
        resolver: { sourceExts, assetExts }
      } = await getDefaultConfig();
      return {
        transformer: {
          babelTransformerPath: require.resolve(
            "react-native-svg-transformer/react-native"
          )
        },
        resolver: {
          assetExts: assetExts.filter((ext) => ext !== "svg"),
          sourceExts: [...sourceExts, "svg"]
        }
      };
    })();
  4. Configure Metro for React Native v0.72.1 or newer

    master

    For modern React Native projects (v0.72.1+), merge this configuration into your metro.config.js using mergeConfig from @react-native/metro-config.

    const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");
    
    const defaultConfig = getDefaultConfig(__dirname);
    const { assetExts, sourceExts } = defaultConfig.resolver;
    
    /**
     * Metro configuration
     * https://reactnative.dev/docs/metro
     *
     * @type {import('metro-config').MetroConfig}
     */
    const config = {
      transformer: {
        babelTransformerPath: require.resolve(
          "react-native-svg-transformer/react-native"
        )
      },
      resolver: {
        assetExts: assetExts.filter((ext) => ext !== "svg"),
        sourceExts: [...sourceExts, "svg"]
      }
    };
    
    module.exports = mergeConfig(defaultConfig, config);
  5. Configure Metro for Expo SDK v41.0.0 or newer

    master

    For Expo projects using SDK v41.0.0 or newer, merge the following configuration into your metro.config.js file. This sets the babelTransformerPath to the Expo-specific transformer and updates the resolver to handle .svg files as source files instead of assets.

    const { getDefaultConfig } = require("expo/metro-config");
    
    module.exports = (() => {
      const config = getDefaultConfig(__dirname);
    
      const { transformer, resolver } = config;
    
      config.transformer = {
        ...transformer,
        babelTransformerPath: require.resolve("react-native-svg-transformer/expo")
      };
      config.resolver = {
        ...resolver,
        assetExts: resolver.assetExts.filter((ext) => ext !== "svg"),
        sourceExts: [...resolver.sourceExts, "svg"]
      };
    
      return config;
    })();
  6. Import and use SVG files as React components

    master

    Once configured, you can import .svg files directly into your React components. The transformer converts the SVG into a functional React component, allowing you to pass props like width, height, and fill directly to it.

    import Logo from "./logo.svg";
    
    // Use as a component
    <Logo width={120} height={40} />
  7. Default SVGR configuration for React Native

    master

    When no custom SVGR configuration is provided, the transformer uses the following defaultSVGRConfig. This configuration is optimized for React Native by enabling native: true and using specific SVGO plugins to preserve essential SVG attributes like viewBox and colors.

    {
      "native": true,
      "plugins": ["@svgr/plugin-svgo", "@svgr/plugin-jsx"],
      "svgoConfig": {
        "plugins": [
          {
            "name": "preset-default",
            "params": {
              "overrides": {
                "inlineStyles": {
                  "onlyMatchedOnce": false
                },
                "removeViewBox": false,
                "removeUnknownsAndDefaults": false,
                "convertColors": false
              }
            }
          }
        ]
      }
    }
  8. Create a custom Metro transformer with createTransformer()

    master

    The createTransformer function wraps an existing Metro transformer (like the React Native or Expo Babel transformer) to intercept .svg files. When a file ends in .svg, it uses @svgr/core to transform the SVG source into a React component before passing it to the original transformer. This allows you to use SVGs as components in your React Native project.

    If a .svgrrc or similar configuration file is found in the directory of the SVG, those settings are merged with the defaultSVGRConfig.