Unable to import svg files in typescript

TypescriptSvg

Typescript Problem Overview


In typescript(*.tsx) files I cannot import svg file with this statement:

import logo from './logo.svg';

Transpiler says:[ts] cannot find module './logo.svg'. My svg file is just <svg>...</svg>.

But in .js file I'm able to import it without any issues with exact the same import statement. I suppose it has something to do with type of svg file which must be set somehow for ts transpiler.

Could you please share how to make this work in ts files?

Typescript Solutions


Solution 1 - Typescript

If you use webpack, you can do this by creating a custom types file.

Create a file named custom.d.ts with the following content:

declare module "*.svg" {
  const content: any;
  export default content;
}

Add the custom.d.ts to tsconfig.json as below

"include": ["src/components", "src/custom.d.ts"]

Source: https://webpack.js.org/guides/typescript/#importing-other-assets

Solution 2 - Typescript

Thanks smarx for pointing out use require(). So in my case it should be:

const logo = require("./logo.svg") as string;

which works fine in *.tsx files

Solution 3 - Typescript

  • If you're using create-react-app 2+: docs

Add a custom.d.ts file (I created it on the root path of my src dir) with the correct type (thanks to RedMatt):

declare module '*.svg' {
  const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
  export default content;
}

Install svg-react-loader or some other, then:

  • Use it as the main svg loader
  • Or if you're migrating a codebase and don't want to touch the working part (JS) specify the loader on the import:
import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

Then just use it as a JSX tag:

function f() { 
  return (<MySVG />); 
}

Solution 4 - Typescript

The solution that I found: In ReactJS project, in file react-app-env.d.ts you just remove the space in the comment such as:

Before

// / <reference types="react-scripts" />

After

/// <reference types="react-scripts" />

I hope to help you

Solution 5 - Typescript

You can declare module for svgs the same way as create-react-app:

react-app.d.ts

declare module '*.svg' {
  import * as React from 'react';

  export const ReactComponent: React.FunctionComponent<React.SVGProps<
    SVGSVGElement
  > & { title?: string }>;

  const src: string;
  export default src;
}

see source

Solution 6 - Typescript

If you're using the Create-React-App starter, make sure that the react-app-env.d.ts contains the line:

/// <reference types="react-scripts" />

Solution 7 - Typescript

I had the same issue while trying out a REACT + typescript tutorial.
What worked for me was the following import statement.

import * as logo from 'logo.svg'

Here are my dependencies in package.json.

  "dependencies": {
    "react": "^16.8.4",
    "react-dom": "^16.8.4",
    "react-scripts-ts": "3.1.0"
  },

Hope it helps someone.

Solution 8 - Typescript

There's an alternative way of doing this which we've implemented: make your SVGs components. I did this because it bugged me that I was using commonJS require statements alongside my imports.

Solution 9 - Typescript

I scoured the internet looking for a solution to this issue. This stackoverflow question came up as the top lead, but none of the answers worked for me.

Finally, I was able to come to a solution by trying a few different techniques.

  1. Create an ./globals.d.ts file in the root of your project, at the same place/level your ./tsconfig.json is.

  2. Inside that ./globals.d.ts file, add this:

declare module '*.svg' {
  const content: string;
  export default content;
}

This properly imports the .svg as a string, which is an issue I noticed in the top-rated answer.

  1. Update your tsconfig.json with the following:
{
  "files": ["globals.d.ts"]
}

That's it - that got it to work in my case. I will note - this is in a VanillaJS app.

Solution 10 - Typescript

    // eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />

if you are using the puglin slint it may be that he has disabled thinking it was a comment but not to read the svg you need this type script module just disable the line and be happy

Solution 11 - Typescript

Solution without webpack and custom.d.ts

For me, none of the above solutions worked alone. Because I don't use the Webpack in my current project.

I investigated the outputs in the log, then the following way worked for me, without creating a file (custom.d.ts), changing the config, or installing a new dependency:

const logo: string = require("../assets/images/logo.svg").default;

<img src={logo} alt="logo" />

For svg format you need to add .default, but not for png format.

Solution 12 - Typescript

Hope! This will help someone.

Actually, I tried all the steps but one thing we have to understand, you have to create the custom.d.ts file into the corresponding SVG import folder.

ts config file

{
  "compilerOptions": {
    "target": "ES6",
    "jsx": "react",
    "module": "ESNext",
    "moduleResolution": "Node",
    "baseUrl": "./",
    "paths": {
      "@components/*": ["src/components/*"],
      "@styles/*": ["src/styles/*"],
      "@static/*": ["src/static/*"]
    },
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "isolatedModules": true
  },
  "include": ["src/**/*", "src/static/optional.d.ts"],
  "exclude": ["node_modules", "build"]
}

optional.d.ts

declare module '*.svg' {
    import * as React from 'react';

    export const ReactComponent: React.FunctionComponent<React.SVGProps<
        SVGSVGElement
    > & { title?: string }>;

    const src: string;
    export default src;
}

Finally the common export file:

import Logo from './images/logo.svg';
import BellDot from './images/bell-dot.svg';
import Logout from './images/logout.svg';
import pageNotFound from './images/page-not-found.png';

export {
    Logo,
    BellDot,
    pageNotFound,
    Logout
}

For a better idea:

enter image description here

Solution 13 - Typescript

If you use webpack, install svg-inline-loader, add the module in the webpack.config.js:

{
    test: /\.svg$/,
    loader: 'svg-inline-loader',
}

It works well after building.

If your IDE reports an interactively error, it can solved by adding //@ts-ignore:

//@ts-ignore
import logo from './logo.svg';

svg-inline-loader webpack docs

Solution 14 - Typescript

Import a SVG file in a CRA app

If you want to import a SVG file in a CRA app (create-react-app), without doing any config, you can use one of these methods:

Method 1
import { ReactComponent as MyIcon } from "./assets/images/my-icon.svg";
...
<MyIcon />
Method 2
import myIconFileName from './assets/images/my-icon.svg';
...    
<img src={myIconFileName} />

Solution 15 - Typescript

For me, I had to include react-app-env.d.ts in my tsconfig*.json:

  "include": [
    "src/Router.tsx",        // my main entry point
    "src/global.d.ts",       // global stuff
    "src/react-app-env.d.ts" // react global stuff
  ]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAngryBoyView Question on Stackoverflow
Solution 1 - TypescriptGrahamView Answer on Stackoverflow
Solution 2 - TypescriptAngryBoyView Answer on Stackoverflow
Solution 3 - TypescriptAllenazView Answer on Stackoverflow
Solution 4 - TypescriptjilvanxView Answer on Stackoverflow
Solution 5 - TypescriptkimbaudiView Answer on Stackoverflow
Solution 6 - TypescriptOleksandr DanylchenkoView Answer on Stackoverflow
Solution 7 - TypescriptKiran MohanView Answer on Stackoverflow
Solution 8 - Typescriptendymion1818View Answer on Stackoverflow
Solution 9 - TypescriptadstwlearnView Answer on Stackoverflow
Solution 10 - TypescriptBreno MeloView Answer on Stackoverflow
Solution 11 - TypescriptHamidreza SoltaniView Answer on Stackoverflow
Solution 12 - TypescriptPremjiView Answer on Stackoverflow
Solution 13 - TypescriptcloxnuView Answer on Stackoverflow
Solution 14 - TypescriptEmad ArmounView Answer on Stackoverflow
Solution 15 - TypescriptJosh M.View Answer on Stackoverflow