Skip to main content

Command Palette

Search for a command to run...

Leveraging SVGs in React Native: A Comprehensive Guide

Two approaches to using SVGs in React Native — HOCs for dynamic styling and react-native-svg-transformer for seamless file handling.

Updated
4 min read
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

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

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

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 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 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! 🚀