jacobmischka / gatsby-plugin-react-svg

Adds svg-react-loader to gatsby webpack config
https://www.npmjs.com/package/gatsby-plugin-react-svg
MIT License
70 stars 21 forks source link

Unable to load SVG's from custom folder #34

Open icelandico opened 4 years ago

icelandico commented 4 years ago

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?

Alecell commented 3 years ago

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.

xnyl commented 3 years ago

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.

jacobmischka commented 3 years ago

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.

wesleyguirra commented 2 years ago

Same problem here.

avodynamics commented 2 years ago

I have the same issue.