I have scaffolded a React Library and a Next.js app using the generators. I am wanting to use a svg asset directly in a component but I'm unsure how to import/reference it. In CRA, I was able to do something like import { ReactComponent as MySVG } from 'path/to/my/file.svg'
Duplicate of #1931.
Hmmm... This is related but normally a React application has webpack config. I don't know how that would work with the library since the library has to be able to work in each application's webpack config.
With the approach used in #1964, SVG files would be converted into JavaScript/TypeScript files that export standard React components. This is a mental shift: the SVG files would no longer be "assets" in the normal sense, but would instead be part of the application just like any other React components.
The library would only be exporting JavaScript/TypeScript files, so applications consuming the library would not have to have any special Webpack configurations.
Alright, so in this setup the application wouldn't be handling the SVG files directly anymore, correct?
Correct, at least based on #1964 and the SVGR docs.
Thank you for the explanation. I will close this in hopes that #1964 gets merged soon.
@AdamVig #1964 was merged and released but appears to only target apps.
I am wanting to have a library called @stramel/icons which would export all the React Component versions of my SVGs.
Alternatively, be able to import the SVGs using the @stramel/icons library?
@stramel Sorry, I thought that PR would make it possible to embed SVGs in React libraries. I need that functionality as well.
@AdamVig I'm wondering if the react lib just needs the custom type since the app handles the bundling?
Appears that works. I re-created the react lib for it which added the correct typing to the tsconfig. I'm still unable to get the app to work with the svg files but that should be under #1931. Closing again.
My new tsconfig.json looks like:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"types": ["node", "jest"]
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}
@AdamVig
In our case we would like to handle png files in React components in a React library that gets published with the --publishable flag. Right now we get an error from rollup when we build the dist files: Error: Unexpected character '�' (Note that you need plugins to import files that are not JavaScript).
What would be the best approach?
@sophiestix Hi 👋 we currently don't have the same asset handling available for publishable libraries. I suggest either using an external CSS file to handle images, or alternatively we are working on better asset handling in a future release (soon).
Thank you @jaysoo for the quick response! 🤗
@stramel did you mange to do this? If yes how?
I am wanting to have a library called
@stramel/iconswhich would export all the React Component versions of my SVGs.
@sophiestix Hi 👋 we currently don't have the same asset handling available for publishable libraries. I suggest either using an external CSS file to handle images, or alternatively we are working on better asset handling in a future release (soon).
Oh noes! @jaysoo Any news about it?
@stramel did you mange to do this? If yes how?
I am wanting to have a library called
@stramel/iconswhich would export all the React Component versions of my SVGs.
Yep, I sure did!
my repo/libs/icons/src/index.ts contains one of these lines for each icon.
export { ReactComponent as Activity } from './lib/icn_activity.svg'
I can then just import using import { Activity } from '@stramel/icons'
I don't currently publish my library openly though, so I haven't run into that limitation
FYI I got it to work with a custom rollup config:
/* eslint-disable @typescript-eslint/no-var-requires */
module.exports = (config) => {
const svgr = require('@svgr/rollup').default;
const url = require('@rollup/plugin-url');
console.dir(config, { depth: null });
return {
...config,
plugins: [
...config.plugins,
url(),
svgr({
svgo: false,
ref: true,
titleProp: true,
}),
],
};
};
I really hope nx will add this in the near future as this is the second custom config I'm having for adding SVGR support (the first one is a custom webpack config for StoryBook).
@trumbitta I'm currently trying to create a publishable lib with react and @fluentui/react, but I'm facing issues with theirs svgs as well.
Can you explain-me or provide more details with that approach you have done?
I see issue is closed but I feel like it side tracked to handling icons/SVGs. Still title is "How to handle image assets in React Library" and this is exactly what I have problem with.
When doing stuff like that:
import image from './sample-image.jpg';
Doesn't matter the size, this image gets bundled inline to library dist code (works fine for app bundler). I get why this happens - we do not know what configuration will be used to bundle final app. Still I have to ask is there a better way? Library could inform that in order to use it one needs to use some assets bundling plugins etc.
If there is no other way, perhaps we could at least update docs: https://nx.dev/latest/react/guides/adding-assets-react to inform about different behaviour with libs.