Using svgr with webpack and TypeScript
See original GitHub issueThis isn’t really a question or request for help, rather a suggestion that the docs be updated a bit to help others out so they don’t spend quite as much time fumbling around as I did.
Setting up svgr
as a webpack
loader is wonderfully easy and works right out of the box as described in the docs. However, if you are using TypeScript, you must an ambient type definition in order for the TypeScript compiler to understand what to do with svg files. The typical example looks like this:
declare module "*.svg" {
const svg: string;
export default svg;
}
And this allows you to get the basics working:
import { FC } from "react";
import Logo from "./logo.svg";
const MyLogo: FC = () => ( <Logo/> );
However, if you want to add props to the Logo
component, none of the expected props will be accepted. This is because the ambient type declaration doesn’t adequately describe the component created by svgr. In order to have the component typed correctly, you need the following ambient type definition instead:
declare module "*.svg" {
import React from "react";
const SVG: React.VFC<React.SVGProps<SVGSVGElement>>;
export default SVG;
}
Now, the TypeScript compiler understands that what svgr hands off to you via the import statement is a React component that generates an <svg>
element with the full range of props available to you.
import { CSSProperties, FC } from "react";
import Logo from "./logo.svg";
const logoStyle: CSSProperties = {
fill: "#CF4532",
width: "100px"
};
const MyLogo: FC = () => ( <Logo style={ logoStyle }/> );
One of those things that isn’t immediately obvious and probably should be explicitly stated in the docs.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:25
- Comments:10 (1 by maintainers)
Top GitHub Comments
Isn’t the webpack typescript option supposed to kick out the definition so I don’t need to include a custom.d.ts in every repo with an svg?
But I haven’t had any success getting this to work with webpack in storybook.
Hello, for me I didn’t have to use any
.d.ts
types, I’m using Nextjs and this is how I solved the issues:this is a component located at
@/components/icons/svg/index.tsx
and it loads*.svg
files dynamically from:components/icons/svg
directory.then you can use it as a simple components with all SVG
props
+{ext:"for directory name", icon:"svg file name"}
for usage with React, which doesn’t have the
next/dynamic
package, I think you can replace it withrequire