skip to Main Content

I realized that my project at some point stopped showing svgs which I link from my scss files.

I have lines like:
background-image: url('./assets/icons/check-icon.svg');

Webpack, I suspect it’s the css-loader as I commented all other css-loaders out, now creates hashed svg files like 71348f532d829722222a.svg directly in my dist folder.

The file itself is no svg but JavaScript, probably for using svgs in other places than css:

export default {
      id: "check-icon",
      viewBox: "0 0 512 512",
      url: __webpack_public_path__ + "/Users/USER/Documents/fe/src/assets/icons/check-icon.svg",
      toString: function () {
        return this.url;
      }
    }

Now of course my css is trying to load this file and it cannot be displayed.
Webpack also creates a copy of the actual folders within my dist:
dist/assets/icons/... so if the url() part of my css was not replace with this hashed svg but still would be pointing to url('./assets/icons/check-icon.svg') everything would work. But how can I achieve that?

Here is part of my webpack config:

{
    test: /.s[ac]ss$/i,
    use: [
        'style-loader',
        {
            loader: MiniCssExtractPlugin.loader,
            options: {
                esModule: false,
            },
        },
        {
            loader: 'css-loader', // <--- probably the culprit
        },
        'postcss-loader',
        {
            loader: 'sass-loader',
            options: {
                implementation: require('sass'),
                sourceMap: true,
            },
        },
    ],
}

And here is another part where I test for svgs:

{
    test: /.svg$/,
    use: [
        {
            loader: 'svg-sprite-loader',
            options: {
                runtimeCompat: true,
            },
        },
    ],
    include: [/assets/],
},

If I comment the latter it won’t make any difference though. The file within the css is still linked to the non-working svg with the hash.

2

Answers


  1. Chosen as BEST ANSWER

    Well in my case a fix was using /* webpackIgnore: true */ in front of the SVGs I wanted to use in scss. I have not found an answer which prevents replacement completely, but because I only had a few cases I was a viable solution:

    Something like this.

    /* webpackIgnore: true */
    background: url('./assets/icons/swc_rating_star_icon.svg') repeat-x;
    

    Also described here: https://webpack.js.org/loaders/css-loader/#disable-url-resolving-using-the--webpackignore-true--comment


  2. It’s a while ago I used Webpack and I never was an Webpack-expert – so I just took a look at one of my last config files because I remembered that I had issues with svg as well. So I post the test-parts for .svg files here – hoping it can lead you into the right direction. As you can see I have two tests because I had the problem that Webpack saved all .svg files in my images directory and I didn’t want that for fonts (of type .svg). So the first test is for handling all .svg but beeing fonts and the second for font-svgs.

    exclude font directory on first test

    {
        test: /.svg(?v=d+.d+.d+)?$/,
        exclude: [
            `${settings.dirs.srcPath}fonts`
        ],
        loader: 'url-loader',
        options: {
            publicPath: settings.cssUrlPath,
            limit: settings.build.images.limit,
            mimetype: 'image/svg+xml',
            name: ifProduction(path.join(settings.build.images.dir, `[name]${settings.build.hash ? '.[hash:8]' : ''}.[ext]`), path.join(settings.build.images.dir, '[name].[ext]'))
        }
    },
    

    include only fonts directory on second test

    {
        test: /.svg(?v=d+.d+.d+)?$/,
        include: [
            `${settings.dirs.srcPath}fonts`
        ],
        loader: 'url-loader',
        options: {
            publicPath: settings.cssUrlPath,
            limit: settings.build.images.limit,
            mimetype: 'image/svg+xml',
            name: ifProduction(path.join(settings.build.fonts.dir, `[name]${settings.build.hash ? '.[hash:8]' : ''}.[ext]`), path.join(settings.build.fonts.dir, '[name].[ext]'))
        }
    },
    

    The used variables here are of course project related so you have to adjust that (or remove entirely) according your file-structure. I had a settings.build.images.limit value of 20480. Not sure – I think it was the limit for not writing svg inline as base64 (in css code).

    Like said I’m no expert here – hope this can at least be a good starting point to solve your issue.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search