question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using svgr with webpack and TypeScript

See original GitHub issue

This 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:closed
  • Created 3 years ago
  • Reactions:25
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

10reactions
Jackbennettcommented, May 27, 2021

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?

use: [
  {
    loader: "@svgr/webpack",
    options: {
      typescript: true,
      ext: "tsx",
    }
},
...

But I haven’t had any success getting this to work with webpack in storybook.

8reactions
abdessamadelhamdanycommented, Feb 26, 2022

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:

import dynamic from 'next/dynamic';
import { FC, SVGAttributes } from 'react';

interface Props extends SVGAttributes<SVGElement> {
  ext?: 'svg';
  icon: string;
}

export const Icon: FC<Props> = ({ icon, ext = 'svg', ...props }) => {
  const Icon = dynamic(() => import(`./${ext}/${icon}.svg`));
  return <Icon {...props} />;
};

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 with require

Read more comments on GitHub >

github_iconTop Results From Across the Web

Syntax error when using SVGR with Webpack and configured ...
I managed to get rid of this error using the following setup: First, you need to make svgr emit TypeScript, and then disable...
Read more >
Webpack - SVGR
SVGR provides an official webpack.js loader to import SVG as React components. ... only apply if the SVG is imported from a JavaScript...
Read more >
@svgr/webpack - npm
Start using @svgr/webpack in your project by running `npm i ... TypeScript icon, indicating that this package has built-in type declarations.
Read more >
Generating TypeScript React components from SVG icons ...
Generating TypeScript React components from SVG icons using SVGR. SVGR is a tool that converts SVG files into React components.
Read more >
Using SVGs with Next.js 11 and TypeScript - Duncan Leung
declare module "*.svg" { /** * Use `any` to avoid conflicts with * `@svgr/webpack` plugin or * `babel-plugin-inline-react-svg` plugin.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found