Friday, September 8, 2023
One extra step after configuring @svgr/webpack in TypeScript projects
 views
![Cover photo for One extra step after configuring @svgr/webpack in TypeScript projects](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fq95r71b1uue1%2F2sRTN498ORz8JTSM3iPOZp%2Fda8f6be6345df93a47f1e9125cb62a45%2FSVGR_OG_Image.png&w=3840&q=75)
Problem
You may have followed the steps in the documentation and thought you were done setting @svgr/webpack
. But when you try to import an SVG file, you may encounter the following error.
Cannot find module 'path/to/file.svg' or its corresponding type declarations.
Or if you are doing so in a Next.js project, you may find that the imported component is in any
type.
Cause
This is because TypeScript has no idea what the type *.svg
should become when it is imported into TS files. It is never being instructed or informed. And this is exactly what we are going to do.
Solution
-
Create a declaration file. It can be in any name and in any folder, but for the sake of this example, let's name it
src/types/image.d.ts
. -
Declare the type of the import.
image.d.ts // instruct TS that, when we do // import Svg from './assets/file.svg' // Svg should be in FC<SVGProps<SVGSVGElement>> type // i.e. an SVG component declare module '*.svg' { import { FC, SVGProps } from 'react'; const content: FC<SVGProps<SVGSVGElement>>; export default content; } // instruct TS that, when we do // import svg from './assets/file.svg?url' // svg should be in string type declare module '*.svg?url' { const content: string; export default content; }
If you are doing this in a Next.js project, change the 2nd
declare module
statement to the following.image.d.ts declare module '*.svg?url' { import { StaticImageData } from 'next/image'; const content: StaticImageData; export default content; }
This is because Next.js has a different way of handling static images, which we are not going to cover in details here.
-
Instruct TypeScript to include
image.d.ts
when compilingtsconfig.json { "include": [ // we use a wildcard here, // but you can add src/types/image.d.ts instead if you prefer "src/types/*.d.ts" ] }
If you are doing so in a Next.js project, make sure the added statement goes BEFORE
next-env.d.ts
. This is because Next.js by default declared that importing from*.svg
should returnany
. We need to make sure our declaration overrides Next.js'.tsconfig.json { "include": [ "src/types/*.d.ts", "next-env.d.ts", ] }