Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading svg in css files #141

Open
jan-thoma opened this issue Nov 18, 2020 · 11 comments
Open

Loading svg in css files #141

jan-thoma opened this issue Nov 18, 2020 · 11 comments

Comments

@jan-thoma
Copy link

This is my webpack config for my Vue3 project:

const svgRule = config.module.rule('svg')

        svgRule.uses.clear()

        svgRule
            .use('vue-loader')
            .loader('vue-loader-v16')
            .end()

            .oneOf('inline')
            .resourceQuery(/inline/)
            .use('vue-svg-loader')
            .loader('vue-svg-loader')
            .options({
                svgo: false
            })
            .end()
            .end()

            .oneOf('external')
            .use('file-loader')
            .loader('file-loader')
            .options({
                name: 'assets/[name].[hash:8].[ext]'
            })

        config.module
            .rule('graphql')
            .test(/\.gql$/)
            .use('webpack-graphql-loader')
            .loader('webpack-graphql-loader')
            .options({ removeUnusedFragments: true })
            .end()
    }

When i try to use a svg as background image in my css files like this:

.appWrapper {
    background-image: url('~@/asset/bg.svg');
}

The image in compiled stylesheet in the inspector looks like this:

.appWrapper {
    background-image: url('[Object,Object]');
}

Is this a bug or is my config wrong?

@rickson-simoes
Copy link

Check the 'Vue Cli' tab. May help you, just the way it helped me. 😉

How to use both inline and external svgs

@jan-thoma
Copy link
Author

This example doesn't work with Vue3. It looks like the file-loader in my config returns an object instead of a path which looks like this:

{ __file: '/path/to/file' }

This is maybe more related to webpack instead this plugin.

@serializedowen
Copy link

Any follow ups? I'm experiencing same issue here.

@zefman
Copy link

zefman commented Dec 9, 2020

Yeah same problem here with Vue3

@andreasvirkus
Copy link

andreasvirkus commented Dec 14, 2020

Same problem with Vue2 as well.

Seems related to #64 and the updated docs:
https://vue-svg-loader.js.org/faq.html#how-to-use-both-inline-and-external-svgs

Edit: This might be better, but i currently got neither solutions to work. Will update when I manage to #62 (comment)

@oscars17
Copy link

Any updates? Have the same problem, cant find a proper solution

@drewbaker
Copy link

I'm also very confused with how we are supposed to use SVG's in CSS with this?

@varave
Copy link

varave commented Mar 2, 2021

It works for me with the config from the docs (vue cli tab):
https://vue-svg-loader.js.org/faq.html#how-to-use-both-inline-and-external-svgs

"vue-svg-loader": "^0.16.0"

@chrisb-c01
Copy link

Using vue-cli 3 config, it is working for me using the config from the docs as mentioned by @varave, however replacing babel-loader by vue-loader (I took that from the dev branch).

Config in vue.config.js:

module.exports = {
  chainWebpack: config => {
    const svgRule = config.module.rule('svg');

    svgRule.uses.clear();

    svgRule
      .oneOf('inline')
      .resourceQuery(/inline/)
      .use('vue-loader')
      .loader('vue-loader')
      .end()
      .use('vue-svg-loader')
      .loader('vue-svg-loader')
      .end()
      .end()
      .oneOf('external')
      .use('file-loader')
      .loader('file-loader')
      .options({
        name: 'assets/[name].[hash:8].[ext]',
      });
  }
};

@n4ks
Copy link

n4ks commented Aug 16, 2021

If someone encountered a similar problem with Nuxt, then I was able to fix it by changing:
this
url('~/static/images/fileName.svg)
to this
url('/images/fileName.svg)

@Anatolie
Copy link

For anyone using Vue2, here is how I got it working with Webpack 5:

"vue": "^2.6.14"
"vue-svg-loader": "^0.17.0-beta.2"
"webpack": "^5.41.0"

My rule in webpack.common.js:

{
  test: /\.svg$/,
  oneOf: [
    // SVGs within .scss files: add ?inline to the end to load them: url('example.svg?inline')
    {
      resourceQuery: /inline/,
      type: 'asset/resource',
    },
    {
      use: [
        'vue-loader',
        {
          loader: 'vue-svg-loader',
          options: {
            svgo: {
              plugins: [{ removeDimensions: true }]
            }
          }
        }
      ],
    },
  ],
},

I opted to have the ?inline rule on any non-imported components.

In my SCSS (or CSS) files, I can use SVG backgrounds like so: background-image: url('../images/breadcrumb-chevron.svg?inline'); <-- note the ?inline will have to be added to any SVG URLs in CSS.

And I can still import SVGs as components like normal: import Logo from "../assets/images/logo-black.svg"; in my .vue files!

Webpack 5 discontinued use of file-loader, once I finally figured this out and replaced it with asset/resource, worked like a charm. Hope this helps save someone some time!

cc @andreasvirkus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests