16

I created a typescript app using CRA, with code like this:

import { ReactComponent as Search } from './search.svg' 

It ran fine, and now I want to strip this code into an npm package (library). I created this package by first running CRA again, then removing everything that did not seem relevant (ex. public folder). A simplified version of /dist looks like this:

esm/ icon/ index.d.ts index.js index.d.ts index.js 

This is the original icon/index.ts:

/// <reference types="react-scripts" /> import { ReactComponent as Search } from './search.svg' export const Icons = { Search, } 

This is the compiled icon/index.d.ts:

/// <reference types="react" /> <-- Changed for some reason?? export declare const Icons: { Search: import("react").FunctionComponent<import("react").SVGProps<SVGSVGElement> & { title?: string | undefined; }>; }; 

When I try to run an app that then uses this library, I get the following error:

../dist/esm/common/icon/index.js Attempted import error: 'ReactComponent' is not exported from './search.svg' (imported as 'Search'). 

How do I resolve this?

2
  • Also stuck on this... Looks like npmjs.com/package/@svgr/webpack magic, but have no idea how to add this into build/publish tooling for npm package :( Commented Aug 16, 2021 at 10:32
  • A workaround can be import Logo from '../images/logo.svg' then <img src={Logo} alt="logo" /> Commented Sep 19, 2021 at 12:41

4 Answers 4

5

My original answer wasn't really clear, and it didn't consider the fact that you were using create-react-app.

Since you are using create-react-app the SVGR library is already installed and being used to process SVG files as a ReactComponent.

You can just import them directly like this:

import Search from './search.svg' 

and then use it like so:

export const Component = () => { return ( <div> <Search /> </div> ); } 
Sign up to request clarification or add additional context in comments.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

The reason why it worked earlier and then stopped working after you moved the code into another npm package can be found in the react-scripts webpack config (it is used by CRA).

I faced the same problem while using [email protected], the issue is how the svg loader is applied. Notice the rule is only applicable for the src folder of the target application. So this applied only when the code was in your target package, once it moved to its own npm package, while compiling the app, the react-scripts webpack config will no longer process the svg imports.

The solution is to use these svg imports as string paths (via default exports from the svg files) and then use them as src for your react component.

import searchIconPath from './search.svg'; export const SearchIcon = () => <img src={searchIconPath} />; 

The reason this works is the file-loader is applied on all files.

I believe (looking at the code, I have not tried it) this issue is now fixed in the latest version of react-scripts because the rule is now applied more globally.

Comments

0

for today (12/02/2024) we should add ?react in the end of path to file to make it work

import Search from './search.svg?react' 

Comments

-2

You import svg files as default imports, without brackets.

Below is an example

/// <reference types="react-scripts" /> import Search from './search.svg' export const Icons = { Search, } 

1 Comment

The svgr package (bundled and setup with CRA) allows imports to be used as ReactComponent. This basically sets renders the svg inline, while importing it without brackets essentially just gets the path.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.