How to reference static assets within vue javascript

Viewed 257621

I'm looking for the right url to reference static assets, like images within Vue javascript.

For example, I'm creating a leaflet marker using a custom icon image, and I've tried several urls, but they all return a 404 (Not Found):

Main.vue:

var icon = L.icon({
    iconUrl: './assets/img.png',
    iconSize:     [25, 25],
    iconAnchor:   [12, 12]
});

I've tried putting the images in the assets folder and the static folder with no luck. Do I have to tell vue to load those images somehow?

13 Answers

For anyone looking to refer images from template, You can refer images directly using '@'

Example:

<img src="@/assets/images/home.png"/>

A better solution would be

Adding some good practices and safity to @acdcjunior's answer, to use @ instead of ./

In JavaScript

require("@/assets/images/user-img-placeholder.png")

In JSX Template

<img src="@/assets/images/user-img-placeholder.png"/>

using @ points to the src directory.

using ~ points to the project root, which makes it easier to access the node_modules and other root level resources

Right after oppening script tag just add import someImage from '../assets/someImage.png' and use it for an icon url iconUrl: someImage

this finally worked for me, image passed as prop:

<img :src="require(`../../assets/${image}.svg`)">

What system are you using? Webpack? Vue-loader?

I'll only brainstorming here...

Because .png is not a JavaScript file, you will need to configure Webpack to use file-loader or url-loader to handle them. The project scaffolded with vue-cli has also configured this for you.

You can take a look at webpack.conf.js in order to see if it's well configured like

...
    {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
...

/assets is for files that are handles by webpack during bundling - for that, they have to be referenced somewhere in your javascript code.

Other assets can be put in /static, the content of this folder will be copied to /dist later as-is.

I recommend you to try to change:

iconUrl: './assets/img.png'

to

iconUrl: './dist/img.png'

You can read the official documentation here: https://vue-loader.vuejs.org/en/configurations/asset-url.html

Hope it helps to you!

It works for me by using require syntax like this:

$('.eventSlick').slick({
    dots: true,
    slidesToShow: 3,
    slidesToScroll: 1,
    autoplay: false,
    autoplaySpeed: 2000,
    arrows: true,
    draggable: false,
    prevArrow: '<button type="button" data-role="none" class="slick-prev"><img src="' + require("@/assets/img/icon/Arrow_Left.svg")+'"></button>',

Having a default structure of folders generated by Vue CLI such as src/assets you can place your image there and refer this from HTML as follows <img src="../src/assets/img/logo.png"> as well (works automatically without any changes on deployment too).

I'm using typescript with vue, but this is how I went about it

<template><div><img :src="MyImage" /></div></template>
<script lang="ts">
    import { Vue } from 'vue-property-decorator';
    export default class MyPage extends Vue {
            MyImage = "../assets/images/myImage.png";
        }
</script>

You could define the assets path depending on your environment

const dev = process.env.NODE_ENV != 'production';
const url = 'https://your-site.com';
const assets = dev ? '' : url;
<template>
    <img :src="`${assets}/logo.png`"/>
    <p>path: {{assets}}</p>
</template>
<script>
    export default {
        data: () => ({
            assets
        })
    }
</script>

Ideally this would be inside an utils js file, or as an extended app defineProperty, like:

const app = createApp(component);
app.config.globalProperties.$assets = assets;
app.mount(element);

and will be available as:

<template>
    <img :src="`${$assets}/logo.png`"/>
    <p>path: {{$assets}}</p>
</template>
<script>
    export default {
        mounted() {
            console.log(this.$assets);
        }
    }
</script>

load them in created, mounted or where you need them

async created() {
   try {
      this.icon = (await import('@assets/images/img.png')).default;
   } catch (e) {
      // explicitly ignored
   }

and then

<img :src=icon />

Inside code you can directly require image using.

const src = require("../../assets/images/xyz.png");

Or

In order to dynamically load image need this.

const image = new window.Image();
image.src = require("../../assets/images/xyz.png");
image.onload = () => {
// do something if needed
 };
Related