Transform SVG into React Components using SVGR (2024)

🥐 3 min read

Transform SVG into React Components using SVGR (1)

This article is also available in:

Français

Transform your SVG into React Components using SVGR to create rich React applications with SVG icons.

As a React developer, you've probably found yourself having to integrate SVG into your applications. There are several ways to proceed, the most elegant is to transform your SVG images into React component. We will see here how to go about it.

How to integrate SVG?

There are several ways to integrate SVG into your React application:

1. Use an img tag

const Star = props => (

<img src="star.svg" alt="Star" width="20" height="20" {...props} />

)

This solution is quite viable. You can use SVGO to clean up your SVG and file-loader if you use webpack. However, it has some limitations:

  • An HTTP request by SVG
  • Cannot style SVG (especially color)

2. Use JSX

This solution consists of integrating the SVG directly into the React component in JSX. It has several advantages:

  • No more requests, it's bundled with your JS
  • We can style each part of the SVG
  • "currentColor" allows us to directly inherit the color of the text

Integrating your SVG directly into JSX is the preferred solution for easy maintenance and total control. However, it requires a tricky operation, moving from a SVG file to a React component. At first glance, it's a copy-and-paste, but the JSX is not exactly HTML and it's very tedious when you have a lot of icons.

Switch from SVG to React component

This is where SVGR comes in handy, allowing you to automate the generation of React components from your SVGs. Let's take a concrete example from a SVG generated via Sketch:

<?xml version="1.0" encoding="UTF-8"?>

<svg width="48px" height="1px" viewBox="0 0 48 1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->

<title>Rectangle 5</title>

<desc>Created with Sketch.</desc>

<defs></defs>

<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">

<g id="19-Separator" transform="translate(-129.000000, -156.000000)" fill="#063855">

<g id="Controls/Settings" transform="translate(80.000000, 0.000000)">

<g id="Content" transform="translate(0.000000, 64.000000)">

<g id="Group" transform="translate(24.000000, 56.000000)">

<g id="Group-2">

<rect id="Rectangle-5" x="25" y="36" width="48" height="1"></rect>

</g>

</g>

</g>

</g>

</g>

</g>

</svg>

By typing the SVGR command line:

I get the code of the following component:

import React from 'react'

const SvgComponent = props => (

<svg width="1em" height="1em" viewBox="0 0 48 1" {...props}>

<path d="M0 0h48v1H0z" fill="currentColor" fillRule="evenodd" />

</svg>

)

export default SvgComponent

Pretty cool, no 😏?

Integrate SVGR into my project

There are several ways to integrate SVGR in your project. It's up to you to choose the one that best fits your work habits.

1. Command line usage

To use SVGR as CLI, first install command line:

npm install @svgr/cli

A good way to do this is to add a script to your package.json to automate the SVG transformation.

// package.json

{

"scripts": {

"build:svg": "svgr -d svg/ components/

}

}

The following script transforms each SVG in the "svg/" folder by composing React in "components/".

To run it: npm run build:svg

2. Use webpack

For webpack users, SVGR offers a loader, first install it:

npm install @svgr/webpack

So you can directly import your SVG into your code and let the magic of webpack operate. Just add the loader like this:

// webpack.config.js

module.exports = {

module: {

rules: [

{

test: /\.svg$/,

use: ['babel-loader', '@svgr/webpack'],

},

],

},

}

From now on, you can directly import your SVG as a React component. They will be automatically transformed by SVGR.

import React from 'react'

import Star from 'svg/star.svg'

const App = () => (

<div>

<Star />

</div>

)

3. Use Node.js

The last use, intended for more advanced users, allows you to use SVGR directly in a Node.js script.

Don't forget to install it:

npm install @svgr/core

Here's an example code that programmatically transforms SVG:

import svgr from '@svgr/core'

const svgCode = `

<?xml version="1.0" encoding="UTF-8"?>

<svg width="88px" height="88px" viewBox="0 0 88 88" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->

<title>Dismiss</title>

<desc>Created with Sketch.</desc>

<defs></defs>

<g id="Blocks" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square">

<g id="Dismiss" stroke="#063855" stroke-width="2">

<path d="M51,37 L37,51" id="Shape"></path>

<path d="M51,51 L37,37" id="Shape"></path>

</g>

</g>

</svg>

`

svgr(svgCode, { prettier: false, componentName: 'MyComponent' }).then(

jsCode => {

console.log(jsCode)

},

)

Go further with SVGR

SVGR allows you to go very far in the transformation. A lot of options are available: optimization of SVG, formatting code, adding a title ... I will not go into details but you can find them in the documentation.

Transform your icons

A "font-icon" is a font whose characters have been replaced by icons. Icons have the flexibility of a font, and you can change their size and color via CSS. Transform your SVG into JSX simply with SVGR to create React applications.

It is possible to obtain the same behavior with SVGR, here is an example:

svgr --icon --replace-attr-value "#000000=currentColor" my-icon.svg

We use two options:

  • --icon : set "width" and "height" to "1em"
  • --replace-attr-value "#000000=currentColor" : replaces "#000000" by "currentColor" in all SVG attributes

With these two options you will get the same behavior as a classic "font-icon"!

How SVGR works?

SVGR converts SVG to JSX. To achieve this, it delegates each part of the work to specialized tools:

Let's linger a little on the most delicate phase, the transformation. It allows to pass from a SVG / HTML code to JSX understood by React. Where most libraries go through a series of regular expressions, Babel allows us to apply transformations directly to the HTML AST, namely the DOM. In other words, it breaks down the structure of the code and applies the transformation.

This allows SVGR to apply complicated transformations such as "--replace-attr-value" without any edge effects!

The following code corresponding to the transformation performed when you enable the "replace-attr-value" option. Those familiar with Babel plugins and AST manipulation should not be lost.

const replaceAttrValue = ({ types: t, template }, opts) => {

function getAttributeValue(value, literal) {

if (typeof value === 'string' && literal) {

return t.jsxExpressionContainer(template.ast(value).expression)

}

if (typeof value === 'string') {

return t.stringLiteral(value)

}

if (typeof value === 'boolean') {

return t.jsxExpressionContainer(t.booleanLiteral(value))

}

if (typeof value === 'number') {

return t.jsxExpressionContainer(t.numericl*teral(value))

}

return null

}

return {

visitor: {

JSXAttribute(path) {

const valuePath = path.get('value')

if (!valuePath.isStringLiteral()) return

opts.values.forEach(({ value, newValue, literal }) => {

if (!valuePath.isStringLiteral({ value })) return

valuePath.replaceWith(getAttributeValue(newValue, literal))

})

},

},

}

}

export default replaceAttrValue

This transformation replaces the value of an attribute without any edge effects. It's a lot safer than a regular expression!

For the more curious you can find the code of the project SVGR on GitHub.

I hope that SVGR saves you as much time as it does for me!

Transform SVG into React Components using SVGR (2024)

FAQs

How to convert SVG into React component? ›

Converting an SVG to a React component involves taking the SVG XML code and transforming it into JSX code that can be rendered by React. This process allows you to import SVGs into your React components and manipulate them just like any other element in your React application.

How do I load SVG as React component? ›

Using an SVG as a component

A sample use case would look like this: import { ReactComponent as Logo} from './logo.svg'; import './App.css'; function App() { return ( <div className="App"> <Logo /> </div> ); } export default App; Although this approach is simple to implement, it has some difficulties.

What are the advantages of Svgr? ›

SVG provides several advantages over other raster graphics formats. These advantages include better scalability, smaller file sizes, improved accessibility, greater customizability and SEO-friendliness.

What are the different types of SVG in TS? ›

svg-to-ts offers three different kinds of conversion types; Converting your icons to a single object, converting your icons to constants or converting your icons to single files.

How to use vite plugin svgr? ›

Usage
  1. // vite.config.js import svgr from "vite-plugin-svgr"; export default { // ... plugins: [svgr()], };
  2. svgr({ // svgr options: https://react-svgr.com/docs/options/ svgrOptions: { // ... ...
  3. svgr({ svgrOptions: { plugins: ["@svgr/plugin-svgo", "@svgr/plugin-jsx"], svgoConfig: { floatPrecision: 2, }, }, // ...
Nov 17, 2023

How do I create a dynamic SVG in React? ›

Method 1: Using template literals and data-URI

Copy the SVG contents within a JavaScript template literal `...` and replace the text you want to change dynamically. In the following example to: ${amount}&#8467; Convert the string into a data-uri with "data:image/svg+xml;base64," + btoa(source) and use it as image URL.

How to use SVG as React component in nextjs? ›

The simplest way of using SVGs in a React or Next application is the img tag, as in a regular HTML file. However, as hinted above, Next. js looks for static assets like images in the public directory in your application's root directory.

How do I load SVG with React and Webpack? ›

The easiest way of implementing an SVG in a React app is as follows:
  1. const App = () => <img src="/images/rectangle. ...
  2. import rectangle from 'images/rectangle.svg'; const App = () => <img src={rectangle} alt="" />;
  3. import Image from 'path/image.svg'; const App = () => ( <div> <Image /> </div> )
Nov 20, 2019

Is SVG still relevant? ›

Though still not as widely used as raster file types like PNG, vector graphics are growing fast in popularity. They do some essential tasks that raster images just can't. Here's why people love SVGs. SVG images are scalable.

What are the limitations of SVG files? ›

Limitations of the SVG File Type

Because of the limitations of SVG, the Image size option will have no effect – the size of the SVG in the page will depend on its canvas size or the size of any container it is presented in. You are unable to select an image size. The other options still work e.g. alignment, border etc.

Is SVG HTML or XML? ›

SVG is an application of XML and is compatible with XML 1.0 and with the Namespaces in XML specification.

Is SVG just XML? ›

Scalable Vector Graphics (SVG) is an XML-based markup language for describing two-dimensional based vector graphics.

Is SVG HTML or CSS? ›

SVG is an XML-based language for describing vector images. It's basically markup, like HTML, except that you've got many different elements for defining the shapes you want to appear in your image, and the effects you want to apply to those shapes.

How do I import SVG animation into React? ›

I.) React websites based on Create React App
  1. Step 1.) Add SVG: Add the exported SVG into your project - stopwatch. ...
  2. Step 2.) Create Custom Component: Add your wrapper component ( Stopwatch.jsx in this example) with the structure below: ...
  3. Step 3.) Move Javascript Code: ...
  4. Step 4.) Handle Style Tags:
Mar 2, 2023

How do I import SVG into React next JS? ›

How to import SVGs into your NextJS application
  1. Use SVGR. SVGR is a tool that allows us to import SVGs into your React applications as React components. ...
  2. Use babel-plugin-react-svg. ...
  3. Use next-images. ...
  4. Use a plain image tag. ...
  5. Copy and paste the SVG.

How to import SVG as Vue component? ›

Copy the selected SVG and paste it between the <template> tags in the Vue. js component that we created earlier. After you pasted it, make sure to add the missing closing </svg> tag at the end of the copied code. Now it's time to add the JavaScript that resides between the <script> and </script> tags.

Top Articles
Latest Posts
Article information

Author: Dong Thiel

Last Updated:

Views: 6051

Rating: 4.9 / 5 (59 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Dong Thiel

Birthday: 2001-07-14

Address: 2865 Kasha Unions, West Corrinne, AK 05708-1071

Phone: +3512198379449

Job: Design Planner

Hobby: Graffiti, Foreign language learning, Gambling, Metalworking, Rowing, Sculling, Sewing

Introduction: My name is Dong Thiel, I am a brainy, happy, tasty, lively, splendid, talented, cooperative person who loves writing and wants to share my knowledge and understanding with you.