Home > Software engineering >  How can I use babel to transpile SVGs into React components?
How can I use babel to transpile SVGs into React components?

Time:10-19

I am using Create React App to build a component library. In some of my components, I import SVGs like this:

import { ReactComponent as IconClear } from 'icons/clear.svg';

This works in development, as I know CRA has support for SVGs like this.

I am using @babel/cli to transpile my src/lib folder into a dist folder to use the library as a node package:

rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files

In production, these SVG components don't work. I get the error:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

How can I use babel to transpile these SVGs into components? I don't want to manually have to create components for each SVG and I want to keep the SVG markup intact, so it can still be opened in design software. Is there a babel preset / plugin that can do this?

CodePudding user response:

I was able to accomplish what I needed using the babel-plugin-inline-react-svg package.

I simply installed it: npm install babel-plugin-inline-react-svg --save-dev

Then I added it as a plugin in my babel.config.json.

"plugins": ["inline-react-svg"]

Now when I run my build script, the SVGs are inlined.

The source code:

import { ReactComponent as IconClear } from 'icons/clear.svg';

...is transpiled into:

var IconClear = function IconClear(props) {
  return /*#__PURE__*/_react.default.createElement("svg", props, /*#__PURE__*/_react.default.createElement("path", {
    d: "M12.59 0 14 1.41 8.41 7 14 12.59 12.59 14 7 8.41 1.41 14 0 12.59 5.59 7 0 1.41 1.41 0 7 5.59z"
  }));
};

SVGs now work in production without any errors.

CodePudding user response:

Looks like this package from NPM does exactly what you're looking for, as denoted at the bottom of the relevant SVGR documentation (what CRA uses)

  • Related