chrisgrim's avatar

Dealing with static Images

Hi All, I recently switched in my project from Laravel Mix to Vite and overall I am super happy. However there is one area that seems frustrating to me. With Laravel mix and Vue in my template I could write:

<img  src="/storage/images/vendor/leaflet/dist/marker-icon-2x.png">

and Mix would be able to load the static image easily. However with Vite this no longer seems to be possible. Instead I have to import every image first

import imgUrl from './marker-icon-2x.png'

to be able to use. This is fine if I have one or two images, but sometimes I am loading quite a few static images and it is pretty frustrating that I have to import all of them. Is there no way to do something like

<img  src="/storage/images/vendor/leaflet/dist/marker-icon-2x.png">

in Vite?

0 likes
6 replies
LaryAI's avatar
Level 58

When using Vite, static asset handling is a bit different from Laravel Mix. Vite treats /public as the root for serving static assets, so you should be able to reference images relative to the public directory without needing to import them.

Here's how you can reference your static images in your Vue templates with Vite:

  1. Move your images to the public directory if they are not already there. For example, you might have a structure like this:
project-root/
|-- public/
|   |-- storage/
|       |-- images/
|           |-- vendor/
|               |-- leaflet/
|                   |-- dist/
|                       |-- marker-icon-2x.png
  1. Reference the image in your Vue component using the absolute path from the root of the public directory:
<img src="/storage/images/vendor/leaflet/dist/marker-icon-2x.png">

This should work because Vite will serve files from the public directory as static assets. You don't need to import them as you would with JavaScript modules or other assets that require processing.

If you find that the images are not loading, make sure that the path is correct and that the public directory is configured correctly in your Vite configuration.

Remember that this approach is for static assets that do not need to be processed by Vite. If you need to apply transformations or optimizations to your images, you might still need to import them to leverage Vite's asset handling capabilities.

gych's avatar

I have no issues with this when using Vite.

Do you have a storage link with the public folder?

chrisgrim's avatar

Hi @gych yup when I run symlink I get

php artisan storage:link

   ERROR  The [public/storage] link already exists.

And then when I use

<img src="/storage/images/vendor/leaflet/dist/marker-icon-2x.png">

I get the error

[plugin:vite:import-analysis] Failed to resolve import "/storage/images/vendor/leaflet/dist/marker-icon-2x.png" from "resources/js/PageComponents/Nav/Components/location-search.vue". Does the file exist?

however if I go to my url http://url.test/storage/images/vendor/leaflet/dist/marker-icon-2x.png I can see the image. Here is my Vite config, not sure if it makes a difference

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    resolve: {
        alias: {
            'vue': 'vue/dist/vue.esm-bundler.js',
        },
    },
    plugins: [
        laravel({
            input: [
                'resources/css/app.css', // Your Tailwind entry CSS file
                'resources/js/app.js',
            ],
            refresh: true,
        }),
        vue(),
    ],
});
gych's avatar
gych
Best Answer
Level 29

@chrisgrim Ok I see that you currently just use vue() in vite config, replace it with this

        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }), 

If you want to know what this does and why you need this, check this link from the Laravel docs: https://laravel.com/docs/11.x/vite#vue

1 like
chrisgrim's avatar

@gych OMG amazing. Thank you so much and thank you for providing the link explaining it too!

1 like

Please or to participate in this conversation.