Sep 8, 2023

One extra step after configuring @svgr/webpack in TypeScript projects

Learn to fix SVG import issues in TypeScript with @svgr/webpack by creating a declaration file for accurate type handling.
One extra step after configuring @svgr/webpack in TypeScript projects

This article was written when the SVGR documentation didn’t cover the TypeScript setup. Since then, the documentation has been updated to cover the setup, which is equivalent to the content covered below.

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

  1. 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.

  2. 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.

  3. Instruct TypeScript to include image.d.ts when compiling

    tsconfig.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 return any. We need to make sure our declaration overrides Next.js'.

    tsconfig.json
    {
      "include": [
        "src/types/*.d.ts",
        "next-env.d.ts",
      ]
    }

I'm passionate about 🧠 innovative technologies, 😍 user experience web, and ♿️ accessibility.

Copyright © 2025 KWONG, Matthew Wang Shun