How to reference static assets within vue javascript

Javascriptvue.jsLeaflet

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

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

Example:

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

Solution 2 - Javascript

In a Vue regular setup, /assets is not served.

The images become src="data:image/png;base64,iVBORw0K...YII=" strings, instead.


Using from within JavaScript: require()

To get the images from JS code, use require('../assets.myImage.png'). The path must be relative (see below).

So your code would be:

var icon = L.icon({
    iconUrl: require('./assets/img.png'),   // was iconUrl: './assets/img.png',
//  iconUrl: require('@/assets/img.png'), // use @ as alternative, depending on the path
    // ...
});


Use relative path

For example, say you have the following folder structure:

- src
  +- assets
     - myImage.png
  +- components
     - MyComponent.vue

If you want to reference the image in MyComponent.vue, the path sould be ../assets/myImage.png


Here's a DEMO CODESANDBOX showing it in action.

Solution 3 - Javascript

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

Solution 4 - Javascript

In order for Webpack to return the correct asset paths, you need to use require('./relative/path/to/file.jpg'), which will get processed by file-loader and returns the resolved URL.

computed: {
  iconUrl () {
    return require('./assets/img.png')
    // The path could be '../assets/img.png', etc., which depends on where your vue file is
  }
}

See VueJS templates - Handling Static Assets

Solution 5 - Javascript

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

Solution 6 - Javascript

this finally worked for me, image passed as prop:

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

Solution 7 - Javascript

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!

Solution 8 - Javascript

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>',

Solution 9 - Javascript

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).

Solution 10 - Javascript

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>

Solution 11 - Javascript

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>

Solution 12 - Javascript

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 />

Solution 13 - Javascript

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
 };

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJBaczukView Question on Stackoverflow
Solution 1 - Javascriptazy777View Answer on Stackoverflow
Solution 2 - JavascriptacdcjuniorView Answer on Stackoverflow
Solution 3 - JavascriptMuhammadView Answer on Stackoverflow
Solution 4 - JavascriptYuciView Answer on Stackoverflow
Solution 5 - JavascriptneberaaView Answer on Stackoverflow
Solution 6 - JavascriptJorge EpuñanView Answer on Stackoverflow
Solution 7 - JavascriptJP. AuletView Answer on Stackoverflow
Solution 8 - JavascriptJasonwaidogView Answer on Stackoverflow
Solution 9 - JavascriptDaniel DanieleckiView Answer on Stackoverflow
Solution 10 - JavascriptMichaelView Answer on Stackoverflow
Solution 11 - JavascriptrjcpereiraView Answer on Stackoverflow
Solution 12 - JavascriptFarzad.KamaliView Answer on Stackoverflow
Solution 13 - JavascriptMudassirAfzalView Answer on Stackoverflow