In our react project, we came across a situation when we had to use a third party library and we needed to apply our svg icons on their UI.
One way is to fork and fix it but I prefer if we could do it css whilst still using the sprited svgs.
Is this possible? If not what other option do I have apart from using the unsprited svg as is(which would be a separate request)
Could you provide an example?
We are using the sprited svgs we get from this loader in the below way which is what the example was saying and it works very well.
style={style}
dangerouslySetInnerHTML={{ __html: '' }}
/>
But we are using a third party library 'rc-tree' and we want to apply our own icons for the tree.
They have a className provided their api where we can put out icons and style it.
I was wondering if we can reuse the sprited svg somehow?
@samuelpaulc in this case - no. You should should customize rc-tree classes with following manner:
.override-rc-class {background-image: url('image.svg')} // svg should inlined via url-loader
Oh so I need to use https://github.com/bhovhannes/svg-url-loader right?
@samuelpaulc right
Cool :+1: Thanks Stas
@kisenka But when we use the svg-url-loader, a separate request is made, can it not work together with svg-sprite-loader where it gets sprited?
What you mean saying "a separate request is made"? svg-url-loader inline SVG contents into CSS.
@kisenka
We are also using svg-sprite-loader for our svg images which are used directly in JS as their documentation says and it works well.
Now we are trying to make the svg that we load from within a css class to be also sprited
I am trying this and it does not work.
Using only svg-sprite-loader:
Works well for svgs included in js but if a svg in css is used I get the below error
Error:
Using only svg-url-loader
Works
Using both together
Module build failed: ReferenceError: document is not defined
Order of loaders also dosent help;
Webpack config:
{
test: /.svg$/,
include: 'path/to/svg',
loaders: [
'svg-sprite?' + JSON.stringify({
name: '[name]',
prefixize: true
}),
'svg-url-loader'
]
}
Error I get for this config is
Module build failed: TypeError: Must be an object
Please suggest where I am going wrong and how to get both of these loaders to work together
@samuelpaulc
Use svg-url-loader in CSS and svg-sprite-loader in JS.
@kisenka
Use svg-url-loader in CSS and svg-sprite-loader in JS.
could you provide webpack config example for this?
@lysoff if you want to import SVGs from CSS with svg-url-loader (inline as data-uri) and from JS with svg-sprite-loader I must warn you that this is potential source of collisions of these two loaders. For workaround this you can define svg-url-loader as default loader for SVGs, and exclude some folders which should be processed by svg-sprite-loader:
const svgSpriteFolder = path.resolve(__dirname, 'folder-with-svgs-for-svg-sprite-loader');
...
loaders: [
// default loader for SVG
{
test: /\.svg$/,
loader: 'svg-url-loader',
exclude: svgSpriteFolder
},
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: svgSpriteFolder
}
]
One more way:
.icon1 {
/* SVG will be inlined in CSS */
background-image: url('./foo.svg?inline&fill=red');
}
.icon2 {
/* default way - build a sprite and use SVG fragment identifiers */
background-image: url('./foo.svg&fill=red');
}
Webpack config:
{
module: {
rules: [
...
{
test: /.svg$/,
oneOf: [
{
resourceQuery: /inline/,
use: [
'svg-url-loader',
'svg-fill-loader',
],
},
{
use: [
{
loader: 'svg-sprite-loader',
options: {
esModule: false,
extract: true,
},
},
'svg-fill-loader',
],
},
],
},
]
}
}
Most helpful comment
@lysoff if you want to import SVGs from CSS with svg-url-loader (inline as data-uri) and from JS with svg-sprite-loader I must warn you that this is potential source of collisions of these two loaders. For workaround this you can define svg-url-loader as default loader for SVGs, and exclude some folders which should be processed by svg-sprite-loader: