SVG is an excellent way to develop scalable and responsive visuals. This article introduces SVGs and different methods of using them in a React application.
SVG is an XML-based vector graphic format for designing two-dimensional graphics with great support for interactivity. As the name implies, Scalable Vector Graphics allow us to create visually appealing and dynamic graphics for web applications.
Compared to other raster image formats such as JPEG or PNG, SVGs can free up bandwidth, improve page performance, be rendered at any size without losing quality, and be readily localized by updating the text within them without the use of a graphical editor.
SVG may be used in various use cases when paired with React, a popular JavaScript library for building user interfaces, ranging from simple icons and illustrations to complicated data visualizations and interactive graphics.
This article will look into how to use SVGs in React, briefly introducing what an SVG is, common ways to use SVGs in React applications, and some of the best practices for using SVG in React.
Similar to how HTML provides elements for various components of a webpage, SVG provides elements for circles, rectangles, and simple or complex curves. SVG documents are text files that explain how vector images should be rendered in a web browser or
other SVG-compatible environments. It comprises a <svg>
root element and may include nested elements that define several basic shapes that build a graphic together.
Let’s take a look at some of the most common elements of an SVG component:
<svg>
tag and defines the canvas on which the graphics are rendered. It is a parent tag in which other
SVG elements are nested.
<line>
,
<rect>
and <circle>
, among others.<g>
tag and allows for grouping multiple elements. It acts as a container for grouping related elements.SVG provides several advantages over other raster graphics formats. These advantages include better scalability, smaller file sizes, improved accessibility, greater customizability and SEO-friendliness.
There are multiple ways to use SVG in React, including inline SVG, SVG with the <img>
tag, SVG as a reusable React component and SVG sprites. We will look at these methods in detail in the following sections.
We can use inline SVG directly in React components by including the SVG code as a distinct <svg>
element. It involves embedding the SVG markup directly within the JSX code of a React component.
To see how this works in practice, create a new React application using the create-react-app
templating tool as shown below:
npx create-react-app svg-demo
Next, run the following command in your terminal to start the application on your local server:
npm start
Let’s add a sample SVG element to the App
component in the /src/App.js
file as shown below:
import "./App.css";
function App() {
return (
<div className="App">
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
fill="currentColor"
class="bi bi-google"
viewBox="0 0 16 16"
>
<path d="M15.545 6.558a9.42 9.42 0 0 1 .139 1.626c0 2.434-.87 4.492-2.384 5.885h.002C11.978 15.292 10.158 16 8 16A8 8 0 1 1 8 0a7.689 7.689 0 0 1 5.352 2.082l-2.284 2.284A4.347 4.347 0 0 0 8 3.166c-2.087 0-3.86 1.408-4.492 3.304a4.792 4.792 0 0 0 0 3.063h.003c.635 1.893 2.405 3.301 4.492 3.301 1.078 0 2.004-.276 2.722-.764h-.003a3.702 3.702 0 0 0 1.599-2.431H8v-3.08h7.545z" />
</svg>
</div>
);
}
export default App;
In this example, we directly embed a sample SVG element into the App
component. As a result, the SVG element will be rendered and displayed within the browser.
Using SVG in a React application through this method has several drawbacks. It can make the React file appear bloated and difficult to read. It also has limited reusability, flexibility, and scalability and can cause accessibility problems.
This method involves importing SVG files directly and passing them as the src
prop of an <img>
tag. Setting this up is made easier by Create React App (CRA), which handles
the configurations behind the scenes.
To use this approach, create an assets
folder in the /src directory of the React project and add and add an SVG file to it.
Then, import and use the SVG file in your /src/App.js
file as shown below:
import "./App.css";
import logo from "./assets/instagram.svg";
function App() {
return (
<div className="App">
<img src={logo} alt="" />
</div>
);
}
export default App;
Here, we imported the SVG file and passed it as the src prop of a <img>
tag.
We can already see the SVG in the browser.
It is important to note that the behavior of the SVG is different when using this approach compared to the previous one. Here, the SVG is rendered as an image, which causes it to lose its original vector properties, further limiting its interactivity and style flexibility.
Although this approach is straightforward and convenient, it is not advisable due to its significant limitations.
Using SVG as a reusable React component is a great way to leverage its flexibility and scalability in a React application. It also enables customization throughout the application and leverages React’s component-based architecture to create dynamic and interactive SVGs.
There are different ways to go about this. One way is to manually create a custom React component that returns a particular SVG element, which can be used in other parts of our application. Another option is to rely on automated tools like SVGR, an SVG transformation tool, to handle the conversion process. More information on SVGR will be provided later in this section.
To create a custom React Component, create a Logo.js
file in the src
directory and add the following to it:
export default function Logo({ fillColor }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
fill={fillColor}
class="bi bi-google"
viewBox="0 0 16 16"
>
<path d="M15.545 6.558a9.42 9.42 0 0 1 .139 1.626c0 2.434-.87 4.492-2.384 5.885h.002C11.978 15.292 10.158 16 8 16A8 8 0 1 1 8 0a7.689 7.689 0 0 1 5.352 2.082l-2.284 2.284A4.347 4.347 0 0 0 8 3.166c-2.087 0-3.86 1.408-4.492 3.304a4.792 4.792 0 0 0 0 3.063h.003c.635 1.893 2.405 3.301 4.492 3.301 1.078 0 2.004-.276 2.722-.764h-.003a3.702 3.702 0 0 0 1.599-2.431H8v-3.08h7.545z" />
</svg>
);
}
We created a Logo
component that returns a sample Google SVG icon. The Logo
component can then be rendered in any part of the application. To show the customizability prowess, we
made the fill
property dynamic so that it can be set from a parent component.
To demonstrate this, import and use this component in the /src/App.js
file as shown below:
import "./App.css";
import Logo from "./Logo";
function App() {
return (
<div className="App">
<Logo fillColor="red" />
</div>
);
}
export default App;
In the code above, we imported the Logo
component and set the fillColor
property to red
.
SVGR, on the other hand, is a universal tool that can transform SVG into React components, eliminating the need to create customized React components for each SVG. With SVGR, a raw SVG can be easily transformed into a fully functional React component.
Starting from version 2.0, Create React App now comes with SVGR pre-installed. This lets users directly import SVG files as React components without additional setup, making it a convenient feature right out of the box.
We used Create React App to bootstrap this demo project, so we can immediately see how this works.
import "./App.css";
import { ReactComponent as Logo } from "./assets/google.svg";
function App() {
return (
<div className="App">
<Logo />
</div>
);
}
export default App;
In the code above, the ReactComponent
import is a special syntax that tells webpack to load the SVG as a React component instead of a plain string. The resulting React component can then be renamed as preferred.
The React component will have a JSX syntax, meaning they can be easily customized via props.
When not using Create React App, there are other ways to set up SVG to automate SVG transformations in React-based applications. Click here to learn more.
We can simplify this further by not importing ReactComponent
and instead have the syntax written as shown below:
import Logo from "./assets/google.svg";
Achieving this, however, requires some additional tweaks since we’re using Create React App, which already has some default configurations in place. We need to modify the SVGR configurations already set up by Create React App.
In the /node_modules
folder, open the react-scripts/config/webpack.config.js
file and update the use
property of the SVG section of the config objects
as shown below:
{
test: /\.svg$/,
use: ['@svgr/webpack'],
issuer: {
and: [/\.(ts|tsx|js|jsx|md|mdx)$/],
},
}
Click here for more details on how to work with the webpack loader provided by SVGR.
SVG sprites combine several SVG icons into a single file, known as a sprite, which can then be used to render individual SVGs across an application. SVG sprites can help reduce the amount of HTTP requests made and improve page load times. A single request for the sprite file is made rather than multiple requests to get the individual SVG files used in an application.
An SVG sprite is typically a single file with an svg
tag nesting multiple <symbol>
elements representing each SVG merged to make up the sprite.
To use an SVG sprite, we must define a <use>
element that refers to the <symbol>
element we want to render. The xlinkHref
attribute
of the <use>
element points to the id
of the <symbol>
element.
We can manually create an SVG sprite by creating a distinct <symbol>
element for each SVG we want to combine, but this process tends to be laborious and time-consuming. There are a couple of free tools and
libraries that handle the generation of sprites in seconds.
An example is this website. It uses the svg-spreact module under the hood to select multiple SVG files and combine them into a sprite.
Open the website in your browser and select multiple SVG files by clicking or dropping multiple files into the open space on the website. The website generates the sprite, which can then
be copied and saved in a new .svg
file in any preferred location in your application.
To demonstrate this, create a sprite.svg
file and copy the generated sprite into it. Shown below is how to use a particular SVG from the sprite.
import "./App.css";
import sprite from "./assets/sprite.svg";
function App() {
return (
<div className="App">
<svg>
<use xlinkHref={`${sprite}#instagram`} />
</svg>
<svg>
<use xlinkHref={`${sprite}#google`} />
</svg>
<svg>
<use xlinkHref={`${sprite}#facebook`} />
</svg>
</div>
);
}
export default App;
Here, we imported the sprite. Then we linked to the SVGs using the xlinkHref
attribute of the use
element.
The IDs in the code above link to the sample SVGs that I used in generating the sprite; however, you can always get the id for a particular SVG in a sprite by checking the props on the symbol
element relating to
that SVG.
This is what they look like in the browser.
SVG is an excellent way to develop scalable and responsive visuals for React applications. Developers can generate reusable, performant, and visually attractive graphics for their React applications by importing SVG files directly, leveraging SVGR to create SVG React components, or using SVG sprites. In this article, we’ve introduced SVGs and different methods of using SVGs in a React application.