- How To Integrate SVG For Website And React App With Webpack
- What is SVG
- HTML5 and the SVG format
- State of the support of SVG format
- How to load SVG as an image
- How to inline SVG
- Website integration through Webpack
- React app integration
- How to integrate SVG with create-react-app
- How to integrate SVG with a custom webpack configuration
- How to optimize SVG contents
- Automate SVG optimization with webpack
- Conclusion
- Svg in css webpack
How To Integrate SVG For Website And React App With Webpack
In this post, we will see how to use SVG images in a website and React app. We’ll learn how to integrate, simplify, optimize and automate the use of SVG with Webpack.
What is SVG
- Scalability and resolution: this is the main advantage. It doesn’t use pixels but vector computation, so the image is scalable and is adapted to all screen resolutions.
- High performance: the SVG format is light and, the browser can render it fast.
- DOM styling: the SVG can be inline to the HTML. So, CSS can style it, and javascript can manipulate it as a DOM element.
HTML5 and the SVG format
State of the support of SVG format
SVG stable version is the SVG 1.1-second edition. Almost all browsers have great support for SVG rendering. Note, the specification is not trivial, and browsers don’t implement all specs. For more details about SVG 1.1 browser support, see caniuse.com.
After this introduction, let’s see how to load SVG.
How to load SVG as an image
The IMG tag can load the SVG as an image. With an IMG tag, the image is not vectorial anymore, and the advantage of scalability is lost.
How to inline SVG
Another way to display an SVG is to inline the XML directly into the HTML file. It’s the better way to use SVG because the browser will compute the vectors and keep all advantages of it.
xmlns="https://www.w3.org/2000/svg" viewBox="0 0 100px 100px"> r="50px" cx="50px" cy="50px" fill="#08415c" />
We have seen how to manually add SVG images into a static website. The aim is now to automate this operation with Webpack.
Website integration through Webpack
Almost every website and web app use Webpack as a bundler to apply some operations on the assets. An easy way to make the SVG integration is to use a Webpack plugin to automatically inline the SVG files’ content to the bundled HTML.
Let’s use html-webpack-plugin to manage the HTML files as a template with Webpack. We can use html-webpack-inline-svg-plugin in addition to this one to manage SVG into our HTML template. This plugin can easily inline some SVG’s to HTML files by simply using an IMG tag with an «inline» attribute.
Let’s install these plugins:
# NPM npm install --save-dev html-webpack-plugin html-webpack-inline-svg-plugin # Or Yarn yarn add -D html-webpack-plugin html-webpack-inline-svg-plugin
Now, add some configurations to manage HTML and SVG, add it to webpack.js (or webpack.comon.js if you split the configurations into multiple files).
. otherImports import HtmlWebpackPlugin from "html-webpack-plugin"; import HtmlWebpackInlineSVGPlugin from "html-webpack-inline-svg-plugin"; module.exports = . otherWebpackConfigs, plugins: . otherPluginsConfigs, new HtmlWebpackPlugin( filename: "index.html", template: "src/index.html", chunks: ["main"] >), new HtmlWebpackInlineSVGPlugin( runPreEmit: true, >), >, >;
To inline an SVG, you have to use the IMG HTML tag and add an inline attribute. Webpack will replace the tag and inline the XML from the file.
inline src="src/img/logo.svg">
Note: the image path is a relative path from the project root. It’s because I add src/img/ and not img/ .
We know how to integrate SVG into a static website. Now, let’s see what to do if we use React to construct the frontend.
React app integration
How to integrate SVG with create-react-app
create-react-app is the easiest way to init a React application. It comes with some Webpack configurations.
The first way to load an SVG is to import the file to your component and load it as an image.
import logo from "./img/logo.svg"; const App = () => return div> img src=logo> alt="Logo" /> /div> >
Or to directly inline the XML into the JSX:
const App = () => return div> svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 100px 100px"> circle r="50px" cx="50px" cy="50px" fill="#08415c" /> /svg> /div> >
But, react-script (the component used by create-react-app ) can use the Svgr plugin to convert the imported SVG as a component. The created React component will inline the XML from the SVG file inside the DOM.
import ReactComponent as Circle > from "./img/circle.svg"; const App = () => return div> Circle /> /div> >
Now, we can use SVG with create-react-app, but it is interesting to know more about the configuration of Webpack to convert an SVG image to React component.
Let’s see how to integrate SVG with a custom Webpack configuration for React application.
How to integrate SVG with a custom webpack configuration
We have seen react-scripts use the Svgr plugin to create React component for inlining SGVs in the DOM.
Let’s deep dive into the Svgr configuration with Webpack:
First, install the Svgr webpack plugin:
# npm npm install --dev @svgr/webpack # or with yarn yarn add -D @svgr/webpack
Next, let’s configure Webpack:
module.exports = . otherWebpackConfigs, module: rules: [ . otherAssetsRules, // intercept images format test: /\.(png|jp(e*)g)$/, use: [ loader: "url-loader", options: . loaderOptions > >] >, // intercept svg and use svgr to convert them to React Components test: /\.svg/', use: ["@svgr/webpack"], >, ], >, >;
Finally, let’s import and easily inline an SVG into a component:
import Circle from "./img/circle.svg"; const App = () => return div> Circle /> /div> >
Now, we can use SVG in a website and React app. The last step is to optimize SVG to load it quickly.
How to optimize SVG contents
SVG files can contain redundant and useless information, especially when they are created with an editor. We can safely remove the useless information from the XML. SVGO (SVG Optimizer) is here to automate these operations.
Note: the html-inline-svg-plugin already uses SVGO to optimize SVG before inlining them into the HTML.
# NPM npm install -g svgo # Or Yarn yarn global add svgo
To optimize all SVG files within a directory:
Automate SVG optimization with webpack
Webpack can use SVGO with svgo-loader:
# NPM npm install -D svgo-loader # Or Yarn yarn add -D svgo-loader
Add the loader to Webpack configurations:
module.exports = . otherWebpackConfigs, module: rules: [ . otherAssetsRules test: /\.svg/, use: [. otherLoadersForSVG, 'svgo-loader'], >, ], >, >
Conclusion
W3C creates SVG for the web and, it is good to display a logo, to use some icons or illustrations for a website or a web application. Webpack can easily handle SVG optimization and inlining for complete integration to web apps.
Finally, this article presents the integration for Webpack but, some alternative exists for other bundlers (parcel, . ) and other UI frameworks (VueJS, AngularJS, . ).
Svg in css webpack
SVGR provides an official webpack.js loader to import SVG as React components.
npm install --save-dev @svgr/webpack# or use yarnyarn add --dev @svgr/webpack
webpack.config.js
module.exports =module:rules: [test: /\.svg$/i,issuer: /\.[jt]sx?$/,use: ['@svgr/webpack'],>,],>,>
import Star from './star.svg'const Example = () => (div>Star />/div>)
SVGR let you specify options in a runtime config file like svgr.config.js or directly in the loader:
webpack.config.js
module.exports =module:rules: [test: /\.svg$/i,issuer: /\.[jt]sx?$/,use: [ loader: '@svgr/webpack', options: icon: true > >],>,],>,>
SVGR options reference describes all options available.
You may be interested to use some SVG as an asset (url) and other SVG as a React component. The easiest way to do it is to use a resourceQuery for one of the two type.
webpack.config.js
module.exports =module:rules: [test: /\.svg$/i,type: 'asset',resourceQuery: /url/, // *.svg?url>,test: /\.svg$/i,issuer: /\.[jt]sx?$/,resourceQuery: not: [/url/] >, // exclude react component if *.svg?urluse: ['@svgr/webpack'],>,],>,>
import svg from './assets/file.svg?url'import Svg from './assets/file.svg'const App = () =>return (div>img src=svg> width="200" height="200" />Svg width="200" height="200" viewBox="0 0 3500 3500" />/div>)>
The issuer: /\.[jt]sx?$/ option ensures that SVGR will only apply if the SVG is imported from a JavaScript or a TypeScript file. It allows you to safely import SVG into your .css or .scss without any issue.
.examplebackground-image: url(./assets/file.svg);>
url-loader and file-loader are deprecated over Asset Modules in webpack v5. It is widely encouraged to use resourceQuery method described before.
SVGR can be used with url-loader or file-loader .
webpack.config.js
module.exports =module:rules: [test: /\.svg$/i,issuer: /\.[jt]sx?$/,use: ['@svgr/webpack', 'url-loader'],>,],>,>
import starUrl, ReactComponent as Star > from './star.svg'const App = () => (div>img src=starUrl> alt="star" />Star />/div>)
The named export defaults to ReactComponent and can be customized with the namedExport option.
Please note that by default, @svgr/webpack will try to export the React Component via default export if there is no other loader handling svg files with default export. When there is already any other loader using default export for svg files, @svgr/webpack will always export the React component via named export.
If you prefer named export in any case, you may set the exportType option to named .
By default, @svgr/webpack includes a babel-loader with an optimized configuration. In some case you may want to apply a custom one (if you are using Preact for an example). You can turn off Babel transformation by specifying babel: false in options.
// Example using preacttest: /\.svg$/,use: [loader: 'babel-loader',options:presets: ['preact', 'env'],>,>,loader: '@svgr/webpack',options: babel: false >,>],>