Having difficulty importing SVG files in TypeScript

When working with TypeScript (*.tsx) files, I encountered an issue where I couldn't import an SVG file using the following statement:

import logo from './logo.svg';

The transpiler gave me this error message:

[ts] cannot find module './logo.svg'.
The content of my SVG file is just <svg>...</svg>.

Interestingly, when I tried importing the same SVG file in a .js file, it worked without any problems using the exact same import statement. It seems like there might be some configuration needed for the TypeScript transpiler to recognize the type of SVG file being imported.

Can anyone provide guidance on how to resolve this issue and successfully import SVG files in TypeScript files?

Answer №1

One way to accomplish this task with webpack is by creating a specialized types file.

To start, generate a new file called custom.d.ts and include the following code:

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

Next, append the custom.d.ts file to your tsconfig.json like so:

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

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

Answer №2

Appreciation to smarx for highlighting the use of require(). In my specific scenario, I found success with the following code:

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

This implementation functions effectively within *.tsx files.

Answer №3

Create a file named custom.d.ts (I placed it in the root directory of my src folder) with the appropriate type definitions (credit to RedMatt):

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

Install svg-react-loader or an alternative like this, then:

  • Use it as your main svg loader
  • Or if you are migrating code and prefer not to modify the working section (JS), specify the loader during import:
import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

Now simply utilize it as a JSX tag:

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

Answer №4

After extensive research across various online sources, I came across a stackoverflow query that seemed to have the solution to my problem. However, none of the suggested answers provided a resolution for me.

Determined to find a fix, I experimented with different approaches until I finally arrived at a successful solution.

  1. To tackle the issue, I created an ./globals.d.ts file in the root directory of my project, located alongside the ./tsconfig.json file.

  2. Within the newly created ./globals.d.ts file, I included the following code snippet:

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

This allowed me to import the .svg files as strings, addressing a discrepancy highlighted in the highest-rated response on Stack Overflow.

  1. To finalize the setup, I updated my tsconfig.json with the specified configuration:
{
  "files": ["globals.d.ts"]
}

Following these steps successfully resolved the issue within my VanillaJS application.

Answer №5

The solution that has been discovered: Within a ReactJS project, navigate to the file react-app-env.d.ts and simply remove the space in the comment section like so:

Before

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

After

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

This solution aims to assist you in resolving the issue.

Answer №6

To define a module for SVGs, you can follow the same approach used in 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;
}

Refer to the source code for more details.

Answer №7

Issue with module and type declarations when importing svg files in TypeScript

  1. To resolve this problem, update your ./custom.d.ts file with the following code:
declare module '*.svg' {
  const data: string;
  export default data;
}

Answer №8

When utilizing vite, incorporating the specified compilerOptions into your tsconfig.json resolved the issue I was experiencing:

  "compilerOptions": {
    "types": ["vite/client", "node"],

Answer №9

Resolving the Issue without Webpack and custom.d.ts

None of the previously suggested solutions worked for me individually as I am not using Webpack in my current project.

After examining the log outputs, I discovered a workaround that worked for me without having to create a custom.d.ts file, modify the configuration, or install any new dependencies:

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

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

When dealing with SVG files, remember to add .default, but this is not necessary for PNG files.

Answer №10

When starting with the Create-React-App template, ensure that your react-app-env.d.ts file includes the following line:

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

Answer №11

Believe in the power of hope to assist others.

After attempting all the outlined steps diligently, it is crucial to note that the creation of a custom.d.ts file within the designated SVG import folder is essential.

Here is an excerpt from the 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"]
}

Include this code snippet in your optional.d.ts file:

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

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

    const src: string;
    export default src;
}

Lastly, here's the consolidated export file for convenience:

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 further insights, refer to this image link.

Answer №12

For those looking to add src functionality and turn it into a react component, check out this helpful comment: https://github.com/parcel-bundler/parcel/discussions/7910#discussioncomment-3690319

To implement this, simply include the following code in your globals.d.ts file at the same level as your tsconfig.json:

declare module '*.svg' {
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;

}

Answer №13

During my exploration of a REACT + typescript tutorial, I encountered a similar issue.
The solution for me was to use the following import statement.

import * as logo from 'logo.svg'

Below are the dependencies listed in my package.json file.

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

Hopefully, this information proves helpful to someone else facing a similar dilemma.

Answer №14

One approach we've taken is to transform SVGs into components. I found it cumbersome to mix commonJS require with ES6 import.

Answer №15

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

For those using the plugin slint, it may have been disabled thinking it was a comment. However, in order to read the SVG, you will need this TypeScript module. Simply disable the line and enjoy!

Answer №16

For those utilizing NextJs ^13 in conjunction with TypeScript, here's a helpful guide:

npm install --save-dev @svgr/webpack

As NextJs employs webpack, it's essential to utilize this plugin for processing svg files and incorporating them as React components through file imports. Additional details can be found here about the svgr webpack plugin.

Subsequently, edit your next.config.* file and insert this webpack configuration into the next config:

module.export = {
 // other config values

 webpack(config) {
   config.module.rules.push({
     test: /\.svg$/i,
     issuer: { and: [/\.(js|ts|md)x?$/] },
     use: ['@svgr/webpack'],
   });
   return config;
  }
};

Next, we need to redefine the type definition for svg file content. It should not merely be any, but rather a precise component definition.

Create a customized .d.ts file within your project containing the subsequent code:

// custom.d.ts
declare module '*.svg' {
  const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  export default ReactComponent;
}

Moreover, ensure you import this file in your typescript configuration file - tsconfig.json:

"include": [
 "types/custom.d.ts",
 "next-env.d.ts"
]

The custom declaration file must be included prior to next-env.d.ts. The sequence is crucial.

Everything should now be set up correctly.

import SvgLogo from 'path/to/logo.svg';

function App() {
   return (
      <SvgLogo />
   );
}

Answer №17

If you're still facing issues, attempt to reboot your Integrated Development Environment (such as VS Code). This method worked for me personally.

Answer №18

In order to successfully set up my project, I found it necessary to add react-app-env.d.ts to my tsconfig*.json:

  "include": [
    "src/Router.tsx",        // primary entry point
    "src/global.d.ts",       // global elements
    "src/react-app-env.d.ts" // react specific components
  ]

Answer №19

To get it working for me, I had to add the following line to src/types/images.d.ts

declare module '*.svg';

Then, I imported images like this:

import { ReactComponent as WifiIcon } from '../../../assets/images/Wifi.svg';

In my tsconfig.json file,

I specified the following compilerOptions:

"compilerOptions": {
    "typeRoots": ["node_modules/@types", "src/types"]
}

Hopefully this can benefit someone else trying to achieve the same. I am using the latest version of CRA.

Answer №20

When working with React Native version "0.72.6",

You can create a file named ./globals.d.ts in the main directory of your project, where your tsconfig.json is located.

Include the following lines in globals.d.ts:

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

Avoid adding this information to your tsconfig.json file.

To use it, import like this:

import SVG_google from '.SVG_google.svg';

Answer №21

Need a solution for incorporating SVG files in Vue.js? Look no further! This "svg.d.ts" file contains the code you need to resolve any errors and ensure proper recognition of imported SVG as an actual <svg> element:

declare module '*.svg' {
  import type { SVGAttributes, DefineComponent } from 'vue';

  const content: DefineComponent<SVGAttributes>;
  export default content;
}

Answer №22

For those utilizing Webpack version v6 or higher and aiming to embed an image directly into their code, this method will suit your needs:

const picture = require('./picture.png') as string;

function DisplayImage() {
  return (
    <img src={picture} />  // <img src="data:image/png;base64,..." />
  );
}

To implement this in your webpack.config.js, make the following adjustments:

module: {
  rules: [
    // inline png files (refer to https://webpack.js.org/guides/asset-modules/)
    {
      test: /\.png/,
      type: 'asset/inline'
    }
  ]
}

Keep in mind that if your website has a strict Content-Security-Policy with limited options (e.g. only 'self'), the image may not render properly due to restrictions on inline content.

In such a scenario, you might encounter a broken image display on your webpage along with a warning in the Developer Tools Console. To resolve this issue, include data: in your Content-Security-Policy setup, like so:

Content-Security-Policy: img-src 'self' data:

Answer №23

When utilizing esbuild, it is necessary to include the loader parameter in the esbuild.build function as shown below:

import esbuild from 'esbuild'
await esbuild.build({
  loader: {
    '.svg': 'dataurl',
  },
})

Answer №24

For those utilizing webpack, it is recommended to include the svg-inline-loader by installing it and adding the following module configuration in your webpack.config.js:

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

After building, the setup should function properly.

If any IDE errors are detected, you can resolve them by including //@ts-ignore as shown below:

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

Here is a useful resource on svg-inline-loader in webpack: svg-inline-loader webpack docs

Answer №25

How to Easily Import an SVG File into a CRA App

If you're looking to bring an SVG file into your create-react-app (CRA) without the need for any configuration hassle, here are some simple methods you can follow:

For TypeScript Files

import mySvgIcon from './assets/images/my-svg-icon.svg';
...    
<img src={mySvgIcon} />

For JavaScript Files

import { ReactComponent as MySvgIcon } from "./assets/images/my-svg-icon.svg";
...
<MySvgIcon />

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to fix the "Module parse failed" issue when importing MP3 files in NextJS 14 TypeScript?

Starting a new NextJS project, I used the command npx create-next-app@latest. Within this project, I created a simple TSX component that takes an imported MP3 file as a prop. 'use client'; import Image from "next/image"; import audioI ...

Implementing service injection within filters in NestJS

Looking to integrate nestjs-config into the custom exception handler below: import { ExceptionFilter, Catch, ArgumentsHost, Injectable } from '@nestjs/common'; import { HttpException } from '@nestjs/common'; import { InjectConfig } fro ...

Utilizing HTML and Ionic 3.x: Implementing a for loop within the HTML file by utilizing "in" instead of "of"

I am working with multiple arrays of objects in my typescript file and I need to simultaneously iterate through them to display their contents in the HTML file. The arrays are always the same size, making it easier to work with. Here is what I currently ha ...

The guard check may not be enough to prevent the object from being null

Hello, I am facing an issue with the Object is possibly "null" error message in my Node.js + Express application. How can I resolve this problem? REST API export const getOrderReport = async ( req: Request<{}, {}, IAuthUser>, res: Resp ...

Utilizing Google Analytics 4 in a React TypeScript Environment

Currently, there are two options available: Universal Analytics and Google Analytics 4. The reasons why I lean towards using Google Analytics 4: Universal Analytics is set to be retired on July 1, 2023, so it makes sense to start fresh with Google Analyt ...

How to include subdirectories in a TypeScript npm module

I am in the process of developing a package for npm and I would like it to be imported in the following manner: import myPackage from 'my-package'; import { subFunction1, subFunction2 } from 'my-package/subfunctions'; Upon trying to u ...

Top method for dynamically loading a specific component by using its selector as a variable

I'm currently in the process of developing a straightforward game using Angular. The game is structured to consist of multiple rounds, each with unique characteristics that are distinguished by the variable roundType. For instance, round types can in ...

What is the abbreviation for indicating a return type as nullable?

Is there a way to use shorthand for nullable return types in TypeScript similar to using "name?: type" for parameters? function veryUsefulFunction(val?: string /* this is OK */) // but not this or other things I've tried. // is there a way a ...

The absence of certain attributes in TypeScript

class DeploymentManager { import { observable, action, makeAutoObservable } from "mobx" public deploymentQueue = observable<IDeploymentProject>([]); public inProgressProjects = observable<IDeploymentProject>[]; public s ...

The art of integrating partial rendering into a template

I'm currently working on a project using Angular 2 and I need to display a partial inside a template without having to create a new component. Is this doable? import {Component} from 'angular2/core'; import {RouteConfig, ROUTER_DIRECTIVES} ...

Errors during TypeScript compilation in Twilio Functions

When I run npx tsc, I encounter the following errors: node_modules/@twilio-labs/serverless-runtime-types/types.d.ts:5:10 - error TS2305: Module '"twilio/lib/rest/Twilio"' does not export 'TwilioClientOptions'. 5 import { Twil ...

Leverage the power of TypeScript custom transformer and project reference for enhanced

I am currently working on a project that involves using both project references and custom transformers. The issue I am facing is that project references require the use of TSC for incremental compilation, but when TSC is used, the transformers are not app ...

In TypeScript, make sure to verify the type of an object to avoid any potential compilation errors stemming

Here is the code snippet: export default class App { el: HTMLElement; constructor(el: string | HTMLElement) { if (typeof el === "string") { this.el = document.getElementById(el); } if (typeof el === typeof this.el) { t ...

In order to iterate through a 'IterableIterator<number>', you must either enable the '--downlevelIteration' flag or set the '--target' to 'es2015' or newer

While attempting to enhance my Slider, I encountered an error when utilizing TypeScript React within this Next.js project: "Type 'IterableIterator' can only be iterated through when using the '--downlevelIteration' flag or with a ...

Issue with implementing MUI Style Tag in conjunction with styled-components and Typescript

I have created a custom SelectType component using Styled Components, which looks like this: import Select from '@mui/material/Select'; export const SelectType = styled(Select)` width:100%; border:2px solid #eaeaef; border-radius:8px ...

Error encountered: The database is not found during the migration creation process in MikroORM

Attempting to create migrations with mikroORM has been a challenge as I am unable to generate the table itself. The error message indicating that the database "crm" does not exist leaves me puzzled about what steps I may have missed. Here is the code snip ...

Typescript: When using ts-node-dev, an error occurred while trying to import express due to an unexpected

I am embarking on a fresh project using Typescript and I intend to set up the node server with typescript utilizing express. There's a helpful tutorial that explains how to execute a Typescript file without going through the hassle of compiling files, ...

Checking the types of arrays does not function properly within nested objects

let example: number[] = [1, 2, 3, 'a'] // this code block correctly fails due to an incorrect value type let example2 = { demo: 1, items: <number[]> ['a', 'b'], // this code block also correctly fails because of ...

Creating a component with @input for unit tests in Angular can be achieved through the following steps

I'm encountering issues while attempting to create a testing component with an @input. The component utilizes properties from the feedback model, and although I imported them into the test file, errors are being displayed. Can anyone offer assistance? ...

Having trouble configuring custom SCSS Vuetify variables with Vue 3, Vite, Typescript, and Vuetify 3

Having some trouble with custom variables.scss in Vuetify. Looking to make changes to current settings and added my code on stackblitz. Check it out here Been going through Vuetify documentation but can't seem to pinpoint the issue. Any assistance w ...