SVG is a vector graphics image format based on XML. SVG stands for Scalable Vector Graphics. It was developed in the late 1990s and was poorly supported until around 2016. Today a huge percentage of icon libraries such as Flaticon, Font Awesome, Material Icon, etc., have full support for SVG. Brands such as Twitter, Youtube, Udacity, Netflix, etc., use SVG for some of their images and icons.
There are other image formats that we are more familiar with such as JPEGs, GIFs, PNGs, etc. We will take a look at some advantages of using SVG over other image formats.
In order to be able to use SVGs or any other image format in the img <img src={} />
we have to set up a file loader system in whichever module bundler we are using(Webpack, Parcel, etc). Here I will show you how to set it up in a few steps if you are already using Webpack.
First, we install the file-loader library $ npm install file-loader --save-dev
, this will install it as a dev-dependency.
And you can update your Webpack configuration file rules with this code:
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
module: {
rules: [
//...
{
test: /\.(png|jp(e*)g|svg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[hash]-[name].[ext]',
},
},
],
},
],
},
//...
};
Now you can import your SVG and use it as a variable, like this:
import React from 'react';
{/*images*/}
import ReactLogo from './logo.svg';
const App = () => {
return (
<div className="App">
<img src={ReactLogo} alt="React Logo" />
</div>
);
}
export default App;
With the same Webpack settings above we can use the SVG tag, basically copying and pasting the content of the .svg
file into your code. Here is a sample use case:
import React from 'react';
const App = () => {
return (
<div className="App">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>
</div>
);
}
export default App;
With this, we can already see the disadvantage of using this method, when the image is more complex the SVG file becomes larger and since SVG is stored in text, that means we have a whole bunch of text in our code.
SVGs can be imported and used directly as a React component in your React code. The image is not loaded as a separate file, instead, it’s rendered along the HTML. A sample use-case would look like this:
import React from 'react';
import {ReactComponent as ReactLogo} from './logo.svg';
const App = () => {
return (
<div className="App">
<ReactLogo />
</div>
);
}
export default App;
Note this approach only works with create-react-app, If you are not using create-react-app, I would recommend using other approaches. Create-react-app uses SVGR under the hood to make it possible to transform and import SVG as a React component.
SVGR is an awesome tool that converts your SVG into React components that you can use. So how do we set it up?
First, we install the package $ npm install @svgr/webpack --save-dev
.
Then we update our Webpack configuration rule to use SVGR for SVGs:
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
module: {
rules: [
//...
{
test: /\.svg$/,
use: ['@svgr/webpack'],
},
],
},
//...
};
Now we can import our SVG images as a React component and use it in our code like this:
import React from 'react';
import ReactLogo from './logo.svg';
const App = () => {
return (
<div className="App">
<ReactLogo />
</div>
);
}
export default App;
Data-urls are URLs prefixed with the data:
scheme that allow content creators to embed small files inline in documents, you can read more about it here. This approach allows us to use SVG images like an inline element.
So how do we achieve this? First, we need an appropriate Webpack loader in our bundler, in the use case, I will be using svg-url-loader. We can grab it into our project by running this command $ npm install svg-url-loader --save-dev
.Then we will update the Webpack configuration file rules section with these rules:
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
module: {
rules: [
//...
{
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {
limit: 10000,
},
},
],
},
],
},
//...
};
Now we can import our SVG file and use it in our React component like this:
import ReactLogo from './logo.svg';
const App = () => {
return (
<div className="App">
<img src={ReactLogo} alt="React Logo" />
</div>
);
}
<img src="ebbc8779488b4073081931bd519478e8.svg" alt="" />
This usually complies into something like this in the DOM
<img src="a34r2dad4234dad7824sa4284r0s2345.svg" alt="React Logo" />
SVGs are really useful for building fast, performant, and accessible webpages. Knowing when and when not to use them will serve you even better. I recommend you use SVGs for low-intensity images like logos, icons, and less-complex images.
#react #web-development #image