# Leveraging SVGs in React Native: A Comprehensive Guide

> Originally written in 2024. Content may vary slightly across newer versions.

Integrating SVGs into React Native applications provides numerous benefits, allowing for dynamic styling and seamless handling of SVG files. This guide outlines **two key approaches** to harnessing the power of SVGs in React Native:

1. **Utilizing Higher-Order Components (HOCs):** HOCs serve as a powerful tool for enhancing the functionality of components in React Native applications. By implementing HOCs, developers can easily modify the color and size of SVG icons dynamically. This approach offers flexibility and reusability, enabling consistent styling across various components.

2. **Leveraging `react-native-transformer` for SVG Handling:** The `react-native-transformer` library facilitates the seamless integration of SVG files into React Native projects. It converts SVG XML text into React components that can be recognized and rendered by React Native, streamlining the management of SVG assets and ensuring compatibility with React Native's rendering engine.
    

#### SVG Transformation with React Native SVG Transformer

```javascript
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 code configures Metro (the React Native bundler) to handle SVG files correctly. By default, Metro doesn't know how to process SVGs, so this configuration is necessary.

Here's what it does:

1. Calls `getDefaultConfig()` to obtain the default Metro configuration.
2. Retrieves the current resolver settings, including supported source and asset file extensions.
3. Adds `.svg` to the list of source file extensions so Metro can recognize and process SVG files.
4. Uses `react-native-svg-transformer` to convert SVG files into React components that can be imported directly.
5. Removes `.svg` from the asset file extensions list, since SVG files are now treated as source files instead.

#### Creating a Higher-Order Component (HOC) for SVGs

```javascript
import React from "react";

import Colors from "theme/Colors";

export const withSvgIcon = (Component) => {
  const WithSvgIcon = ({ color = Colors.primary, width, height }) => {
    return (
      <>
        {width && height}
        ? (
        <Component style={{ color }} with={width} height={height} />
        ) : (
        <Component style={{ color }} />)
      </>
    );
  };

  return WithSvgIcon;
};
```

`withSvgIcon` is a higher-order component (HOC) that wraps an SVG component and exposes three props: `color` (defaults to `Colors.primary`), `width`, and `height`.

When `width` and `height` are provided, they are applied directly to the SVG. Otherwise, the component falls back to its default dimensions.

#### Dynamic Styling of SVGs

```javascript
import React from "react";
import { withSvgIcon } from "./withSvgIcon";
import iconSvgContent from "./assets/icon.svg";

const IconComponent = withSvgIcon(iconSvgContent);

const App = () => {
  return (
    <View>
      <IconComponent color="red" width={20} height={20} />
    </View>
  );
};

export default App;
```

By combining these two approaches, SVG files are transformed into renderable React components with customizable `color`, `width`, and `height` props.

**Recap**

1. **SVG icon import**: Import SVG icons into the project.
2. **Metro configuration**: Set up `react-native-svg-transformer` to handle SVG files.
3. **`withSvgIcon` HOC**: Add dynamic styling capabilities to SVG components.
4. **Usage**: Use the styled SVG icons within your React Native components.

#### Troubleshooting

**Why isn't the `color` prop changing my SVG icon's color?**

Make sure the `fill` attribute in your SVG file is set to `currentColor`. Without this, the `color` prop has no effect — the SVG will render with its hardcoded fill instead of inheriting the color from the parent component.
    

**Example:**

In your SVG file, set `fill="currentColor"` on the path:
```svg
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z"/>
</svg>
```

`currentColor` tells the SVG element to inherit the text color of its parent — which is how the `color` prop gets applied.

**Still running into issues?**

Check the [react-native-svg-transformer documentation](https://github.com/kristerkari/react-native-svg-transformer) for dependency requirements and Metro configuration differences across React Native versions.

Don’t hesitate to drop a comment, hit that follow button for more React Native goodness! 🚀
