eylay
eylay

Reputation: 2160

How to include images in Vue Components in vite and laravel 10

In one of my Vue Components, for example Login.vue I have used an img tag to display an image :

<img class="logo-img" src="/assets/img/logo.png" alt="...">

Then in my terminal I run npm run dev and everything works just fine and image will be displayed with no problem.

Now when I run npm run build I face following error :

[vite]: Rollup failed to resolve import "/assets/img/logo.png" from "C:/Users/Ali/Desktop/Projects/ajorplus/resources/js/Pages/Auth/Login.vue". This is most likely unintended because it can break your application at runtime. If you do want to externalize this module explicitly add it to build.rollupOptions.external error during build: Error: [vite]: Rollup failed to resolve import "/assets/img/logo.png" from "C:/Users/Ali/Desktop/Projects/ajorplus/resources/js/Pages/Auth/Login.vue". This is most likely unintended because it can break your application at runtime. If you do want to externalize this module explicitly add it to build.rollupOptions.external at viteWarn (file:///C:/Users/Ali/Desktop/Projects/ajorplus/node_modules/vite/dist/node/chunks/dep-abb4f102.js:48051:27) at onRollupWarning (file:///C:/Users/Ali/Desktop/Projects/ajorplus/node_modules/vite/dist/node/chunks/dep-abb4f102.js:48083:9) at onwarn (file:///C:/Users/Ali/Desktop/Projects/ajorplus/node_modules/vite/dist/node/chunks/dep-abb4f102.js:47814:13) at file:///C:/Users/Ali/Desktop/Projects/ajorplus/node_modules/rollup/dist/es/shared/node-entry.js:24070:13 at Object.logger [as onLog] (file:///C:/Users/Ali/Desktop/Projects/ajorplus/node_modules/rollup/dist/es/shared/node-entry.js:25742:9) at ModuleLoader.handleInvalidResolvedId (file:///C:/Users/Ali/Desktop/Projects/ajorplus/node_modules/rollup/dist/es/shared/node-entry.js:24656:26) at file:///C:/Users/Ali/Desktop/Projects/ajorplus/node_modules/rollup/dist/es/shared/node-entry.js:24616:26

Why when I run npm run dev it works just fine, and when I run npm run build I face this error? How can I fix this problem?

Upvotes: 3

Views: 3459

Answers (3)

eylay
eylay

Reputation: 2160

If you want to use content inside your public folder, it's easy, you just add a / at the beginning of your path:

<img src='/assets/img/example.png' />

But, if you have located your content inside resources folder, then it becomes a bid tricky.

Imagine your working directory looks something like this :

resources
|____ images
|     |____ map.jpg
|____ js
|      |____ Pages
|            |_____ Test.vue
|
|____ css // its content (not important in this example)
|____ views  // its content (not important in this example)

Then inside your Test.vue file, You normally include your image this way:
(There is a better way which I am going to mention)

<img src="../../images/map.jpg">

First of all when you use multiple '../'s, your path looks ugly, and second of all if in future you decide to relocate your component you have to modify the path again.

So, it's better to define alias. If we add following block inside vite.config.js file, 2 aliases will be defined:

export default defineConfig({
    plugins: [
        ...
    ],
     // ↓↓↓↓ ADD THIS ↓↓↓↓
    resolve: {
        alias: {
            "@": "/resources",
            "@img": "/resources/images",
        },
    },
});

Now that we have added 2 new aliases there are 2 ways to write your path:

First Way

<img src="@/images/map.jpg" />

Second Way

<img src="@img/map.jpg" />

This way, you no longer have to write all those '../'s in your path

Upvotes: 1

FW4lk3r
FW4lk3r

Reputation: 1

I've found this beautiful tutorial: https://medium.com/@andrewmasonmedia/how-to-use-images-with-vite-and-vue-937307a150c0

But for you case I think this is what you want:

<script setup>
import imgUrl from './assets/img.png'
</script>

<template>
  <img :src="imgUrl" />
</template>

Upvotes: 0

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

One issue that I see is that you are trying to bundle your image asset with an "absolute path": you start the path with a back slash, src="/assets/img/logo.png". As such, it will not be included in the build. You will either want to include the resource yourself in the public file or a file off of public or use a relative path to the resource (not starting the path with a backslash).

Reference: Laravel 10 Documentation #URL Processing

Which states:

URL Processing

When using Vite and referencing assets in your application's HTML, CSS, or JS, there are a couple of caveats to consider. First, if you reference assets with an absolute path, Vite will not include the asset in the build; therefore, you should ensure that the asset is available in your public directory.

When referencing relative asset paths, you should remember that the paths are relative to the file where they are referenced. Any assets referenced via a relative path will be re-written, versioned, and bundled by Vite.

Consider the following project structure:

public/
  taylor.png
resources/
  js/
    Pages/
      Welcome.vue
  images/
    abigail.png

The following example demonstrates how Vite will treat relative and absolute URLs:

<!-- This asset is not handled by Vite and will not be included in the build -->
<img src="/taylor.png">
 
<!-- This asset will be re-written, versioned, and bundled by Vite  -->
<img src="../../images/abigail.png">

Upvotes: -2

Related Questions