For React projects created with create-react-app
, you can not import an SVG as ReactComponent
, and that adds it as an inline SVG. In Gatsby it doesn’t work.
This code would not work
1import { ReactComponent as Logo } from './logo.svg'
2function App() {
3 return (
4 <div>
5 {/* Logo is an actual React component */}
6 <Logo />
7 </div>
8 )
9}
You’ll get the following error instead
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Importing the SVG as an image would work. But that’s an image, defeats the entire purpose of using an SVG in the first place. You can not make an image file show different variants based on media queries in a straightforward and contained way. Besides, Gatsby’s own <Image>
component is great for static images.
1import logo from '../assets/img/logo-responsive.svg'
2
3function App() {
4 return (
5 <main>
6 {/* the SVG will show as an image and will not be used as an inline SVG */}
7 <img src={logo} alt="logo" />
8 </main>
9 )
10}
So we gotta create a component for icons that’ll return SVGs based on the name
we pass to it.