Webpack and "#" in URL() - vue.js

<img src='#/assets/image.jpg'> works fine, and is translated into /static/img/image.xxxxx.jpg. However trying to use it in CSS like background-image:url('#/assets/image.jpg'); does not work. It is left unchanged in the resulting html. Using Vue, but I believe it is Webpack that is doing the expansion of "#".

In the <style> tag and CSS files, URLs with aliases must be prefixed with ~, which tells Webpack that the path is not relative to the current directory and requires path resolution. Your CSS should look like this:
background-image: url('~#/assets/image.jpg');

Related

How do I use images from the public directory in my vue app(not the assets folder)?

If I include images from the assets folder(in src besides App.vue) it will build and run but then not work when changing it with javascript.Eg.:
background-image: url('../assets/img/bg_b.png');
// If I than change it with javascript it doesn't work
background-image: url('../assets/img/bg_w.png');
// I then need to use it like this
background-image: url('/img/bg_w.png');
I want to use images from my public folder in vue so the line is the same in javascript and vue. How do I make using an image look the same in vue and browser:
background-image: url('/img/bg_w.png');
If the image URL is /img/bg_w.png, the file should be in:
public/img/bg_w.png
demo

How do I access assets path with external scss file in Nuxt?

I'm using Nuxt and I have an external scss file, how can I access assets path to use the background-image property?
I have already tried to use this background-image: url("~assets/images/myurl.png") but it didn't work.
I tried using the inline style and it worked but is there any other way without using the inline style?

VueJS & v-html: How do I prepend the baseURL to asset links in imported HTML?

Apologies if this explanation isn't super clear. I am new to VueJS and I will do my best to explain my predicament.
I am building an application that imports html from external files into a component using v-html. I achieved that without any problems. However, the html has a bunch of asset urls that start with a /. What I want to do is to ensure that every asset url that starts with a / has a baseURL placed in front of it, converting it from say '/some-folder/some-asset.jpg' to '../../static/some-folder/some-asset.jpg' automatically without me having to programmatically modify the url.
I have tried modifying settings in the configuration file index.js, namely by trying different urls in assetsSubDirectory and assetsPublicPath but without success.
This is an example of a node in the imported html:
<picture>
<source media="(min-width: 768px)"srcset="/media/3974/cover_tablet.jpg">
<img id="img_20921" src="/media/3973/cover-mobile.jpg" class="img-fluid">
</picture>
I am trying to change the src value of:
/media/3974/cover_tablet.jpg
to:
../../static/media/3974/cover_tablet.jpg
by setting a base URL in the vue configuration but it won't prepend ../../static to the url and therefore the app cannot find the relevant asset.
The only way I managed to get this to work is by using JQuery to look for "src:" strings in the imported html and then prepend the baseURL into the link. This isn't at all ideal though and what I really want to achieve is for any link that starts with a "/" to have the apps baseURL prepended to it automatically.
I am starting to wonder if it is even possible for urls in imported html to pick up the apps baseURL value?
I found a solution. I was using the webpack template for my project which proved to make this particular issue difficult to work out so I reset my project using the Vue CLI template instead, put all my assets in the public folder and all the links in my imported html were picked up immediately with no fuss and no messing around with webpack configuration.

vue access to images

I'm trying to view an image in one of my pages. I'm on a latest node-express-vue-nuxt-babel setup. My final goal was:
<img :src="'#/assets/images/projects/' + project.image" width="50px" />
I started with the above, but I got a 404. So I tried with a specific image:
<img src="#/assets/images/projects/5a2db62e346c1.jpg" width="50px" />
and it worked, but going back to dynamic source didn't and:
to <img :src="'#/assets/images/projects/5a2db62e346c1.jpg'" width="50px" />
was enough to produce the 404 again. The 404 was in the console, the page was loading fine with no errors but alas no signs of the image(s). Inspecting the elements made me notice that the dynamic :src became:
<img src="#/assets/images/projects/5a2db62e346c1.jpg" width="50px" />
and the 'static' src became:
<img src="/_nuxt/assets/images/projects/5a2db62e346c1.jpg" width="50px" />
So to make it work I had to renounce to the initial "#" and substitute it with "_nuxt":
<img :src="'_nuxt/assets/images/projects/' + project.image" width="50px" />
Ok, nice, but.. why?
Do this: <img :src="require('#/assets/images/projects/' + project.image)"/>
VueJs
There are several asset URL transforms rules in vuejs. Here is one of them:
If the URL starts with #, it's also interpreted as a module request. This is useful if your webpack config has an alias for #, which by default points to /src in any project created by vue-cli
For more information : Asset URL
You are using webpack for bundling the application.
At a very high level webpack looks for require and takes care of bundling your scripts. Exactly what that means depends on your specific configuration, but it usually gathers all the js files in one file, usually minifies and removes unused code.
Webpack is not limited to js files. By the use of plugins it can handle extracting images from html files, load resources from urls and much more.
The way it ends up loading images is still by the use of require, the plugins just plug everything in so webpack can handle them. That being said, require is a compile time feature and if the path can't be determined at compile time webpack will not work. Webpack will usually translate the image path to a path that's available at runtime (usually they are different and depend on your webpack config).
When you bind src like this:
:src="'#/assets/images/projects/' + project.image"
The path can't be determined at compile time and as such vue will resolve it at run time, but webpack already finished and it will not translate your path.
There are a couple of ways to handle this:
As you found out: using a static runtime path, that is not handled by webpack, will work. The downfall is that if you change the way you build your project you'll need to update all references (in your case _nuxt). Note: if using vue.cli, you usually get a folder called static that is used exactly for this.
Use a binding, but bind to the run time path. This has the same downside as above and also the following: webpack has cache-busting technics that mangle file names, so knowing the final name of an asset that is handled this way by webpack is virtually impossible.
It worked also with backticks:
<img :src="require(`#/assets/images/projects/` + project.image)" width="100px" />
Thanks guys!

Module not found: Error: Can't resolve 'assets/img vue.js

I have following structure:
-src
-assets
-css
-img
-js
In my style.css I have this line:
background: url(~assets/img/arrows.png) no-repeat;
And get this error
Module not found: Error: Can't resolve 'assets/img/arrows.png'
what do I do?
I tried to write ./assets/, ../assets/ , ./src/assets still doesn't work
If you've imported the css file in App.vue or any other .vue file make sure the url is relative to that *.vue file
This issue can come up in Nuxt.js projects. If you're seeing this issue there, you'll have to either use a tilde (~) with no slash in front of the absolute path or you have to use a tilde and an at sign (#), so either this:
background-image: url('~assets/img/arrows.png');
Or this:
background-image: url('~#/assets/img/arrows.png');