gatsby-plugin-react-svg
gatsby-plugin-react-svg copied to clipboard
Unable to load SVG's from custom folder
I keep my svgs in src/images/svgs directory. Then I try to load them in component in such way:
import Icon from "../../images/svgs/icon.svg"
In gatsby-config.js i have following config:
rule: {
include: /images\/svgs/
}
I was trying to do it also like this: /images(\/|\\)svgs/ and include: path.resolve(__dirname, 'src/images/svgs')
The last way doesn't even throw an error, it just blocks the browser and I have to close it and re open browser.
If I'm able to get error i have this one:
InvalidCharacterError: Failed to execute 'createElement' on 'Document':
The tag name provided ('data:image/svg+xml;
Which means that my configuration is wrong, how?
How to make this plugin working?
Apparently if your config match something that isn't SVG you get that error, maybe on svg folder has a file that isn't a SVG file. Thats an opinion based on experience, I don't delve in the code.
It is because .svg files are still being consumed by the url-loader plugin. Here is why:
The problem is in this conditional configuration:
const newUrlLoaderRule = (include || exclude) ? {
...imgsRule,
include: exclude,
exclude: include
} : {
...imgsRule,
test: new RegExp(imgsRule.test.toString().replace('svg|', '').slice(1, -1))
}
If you explicitly specify include: /images\/svgs/, the final url loader configuration will be:
{
use: [
{
loader: '/.../node_modules/url-loader/dist/cjs.js',
options: [Object]
}
],
test: /\.(ico|svg|jpg|jpeg|png|gif|webp|avif)(\?.*)?$/,
include: undefined,
exclude: /images\/svgs/
}
If you leave options empty, like this:
plugins: [
{
resolve: "gatsby-plugin-react-svg",
options: {},
},
it will be:
{
use: [
{
loader: '/.../node_modules/url-loader/dist/cjs.js',
options: [Object]
}
],
test: /\.(ico|jpg|jpeg|png|gif|webp|avif)(\?.*)?$/
}
Here the test entry is modified and skips svg from being consumed by the url-loader.
So it seems that having |svg| in the test both with exclude/include regexes is not working as expected - url-loader is still processing those images before svg-loader. That is probably a bug.
Honestly, I don't use gatsby anymore these days, ~and I haven't used this library myself since before the 3.0 release,~ but specifying include works fine for me in ^2.0 in older gatsby projects and the logic still seems correct to me; when specifying include, those paths will be excluded by url-loader, so I still don't see what the issue is despite your examples above.
Pull requests welcome, surely.
Edit: I updated an older project to use gatsby 3 and the most recent version of this plugin, and specifying include still indeed works.
gatsby-config.js:
{
resolve: 'gatsby-plugin-react-svg',
options: {
rule: {
include: /icons/
}
}
},
index.js:
...
import TeamIcon from '../images/icons/team.svg';
export default function IndexPage({ data }) {
return (
<Layout
title={data.site.siteMetadata.title}
className="home"
>
<TeamIcon />
</Layout>
);
}
SVG icon is rendered correctly.
Same include but with this config results in an error:
{
resolve: 'gatsby-plugin-react-svg',
options: {
rule: {
include: /icfons/
}
}
},
So I'm not sure what's going on causing it to not work for you.
Same problem here.
I have the same issue.