18

Is it possible to include an image, which is in assets/ foder, in some static .scss file, as a background-image?

I have a _buttons.scss partial and some buttons have an icon, which I'd like to add as a background-image. The icons are located in src/assets/ foder.

App structure:

- src
  - assets
    some_icon.svg
  - components
  - scss
    _buttons.scss
    main.scss
  - views
  App.vue
  main.js
  router.js

And in _buttons.scss:

.some-selector {
    background-image: url(../assets/some_icon.svg)

    /* also tried
    background-image: url(./assets/some_icon.svg)
    background-image: url(/assets/some_icon.svg)
    background-image: url(assets/some_icon.svg)
    */
}

Which returns an error with This relative module was not found.

I know I can simply add those styles (scoped or not) in my component, or in main App.vue, however, I was wondering if this can be achieved without that?

I know also that I can add those icons in my public folder but I would like for the icons to remain in the assets/ folder.

$ vue -V
$ 3.0.0-rc.5

Maybe some custom webpack config?

Thanks

Vucko
  • 20,555
  • 10
  • 56
  • 107
  • I think this answer solves your problem [Resolving background-image URLs in CSS files for Webpack](https://stackoverflow.com/questions/45597788/relative-css-urls-in-webpack) – Max Sinev Jul 26 '18 at 07:18
  • How are you using the `main.scss` file? I'm importing it in the `main.js` file and that relative import works for me. – Luis Orduz Jul 31 '18 at 18:53
  • @LuisOrduz I have `@import 'main.scss'` in my `App.vue` file. Is that a good practice to import the .scss file in the main.js? – Vucko Aug 01 '18 at 04:44
  • @Vucko It's perfectly fine to import `main.scss` from `App.vue`. And I can't reproduce the error unless I try a nonexistent URL for `background-image`. Also note that `../assets/some_icon.svg` is correct. Do you have a repo to look at? – tony19 Aug 01 '18 at 06:42
  • @tony19 just tried what you've suggested and it really works. Didn't know that you can import in `main.js` the `.scss` files. Can you please explain a little bit why it works as an answer and I'll accept it. – Vucko Aug 01 '18 at 06:48
  • I'm glad it works for you, but I didn't really suggest anything. I merely stated I tried your code exactly as you described, and I couldn't reproduce the problem :) You can import `main.scss` from either `main.js` or `App.vue`, but I personally prefer importing CSS from `*.vue` files and only app setup code in `main.js`. – tony19 Aug 01 '18 at 06:52
  • Does it work with background-image: url(/assets/some_icon.svg)? It works on my site with trailing slash path like that. Because the level of the component is not the same the level of the css files. when you import the scss, the relative path will be the relative path in the component, not in the scss file. – Dat Tran Aug 05 '18 at 02:42
  • try using ~/assets/some_icon.svg – Saeed Aug 05 '18 at 06:49

1 Answers1

44

You can manage that by :

background-image: url('~@/assets/some_icon.svg');

Key here is using ~@ as a prefix. URLs prefixed with ~ are treated as a module request. You need to use this prefix if you want to leverage Webpack's module resolving configurations. For example if you have a resolve alias for src folder equal to @, which you do if you use vue-cli3, you can use this type of URL to force Webpack to resolve to the needed asset in the assets folder. More info here: handling static assets

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Saša Šijak
  • 8,717
  • 5
  • 47
  • 82