Molod's avatar
Level 4

Vite and css url() path

Hello,

what's a correct file path for css background-image using vite?

Here is my code:

  .webp & {
    background-image: url(/images/webp/hero-bg.webp);
  }

And I get 404 error in browser in dev mode:

GET http://localhost:5173/images/webp/hero-bg.webp 404 (Not Found)

But it's all good in production build.

I tried to use relative path - it's went good in dev mode, but it's not found in production build.

My vite.config.js:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

const path = require('path');

export default defineConfig({
  server: {
    host: '127.0.0.1',
  },
  resolve: {
    alias: {
      '~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap'),
    }
  },
  plugins: [
    laravel({
      input: [
        'resources/sass/app.scss',
        'resources/js/app.js',
        'resources/js/navigation-drawer.js',
        'resources/js/modernizr-custom.js',
      ],
      refresh: true,
    }),
  ],
});

.env:

...
APP_URL=http://127.0.0.1:8080
...

public/hot:

http://127.0.0.1:5173

I use php artisan serve --port 8080 for a local dev server

0 likes
13 replies
Sinnbeck's avatar

@Molod Ok strange. I cannot recreate it. My url isnt changed at all in the browser

background-image: url(/images/webp/hero-bg.webp);
mhyeganeh's avatar

Same issue here. Did you found any solution...?

I can not load my fonts and static images located in public directory and refferenced inside scss files in dev server mode using vite.

I used it inside styles like this:

background-image: url(/images/test.jpg);

the browser is looking for this url which can not find (404):

http://my-domain.test:5173/images/test.jpg

And if I type below links in browser it's ok:

http://my-domain.test/images/test.jpg

http://my-domain.test:5173/public/images/test.jpg

What's the right pattern to refferece assets in public directory?

Sinnbeck's avatar

@mhyeganeh can you share a reproducible example like a github repo. I set it up myself and had no problems

naknak987's avatar

If you move your static assets to the resources directory then in your css/scss reference them from the resources directory.

background-image: url(/resources/images/test.jpg);

Vite will then serve your assets from the resources directory during development, npm run dev, but when you build for production, npm run build, it will compile the URL to the public path /build/assets/test.1a04fbd3.jpg. This works fine for me out of the box in a new Laravel project with no extra config.

The extra bit added when you build for production, 1a04fbd3 , is the way that Vite versions assets.

12 likes
xingredient's avatar

@naknak987 What if I do not want Vite to version assets and load it from my public folder?

When letting Vite handle my assets, I have the images in my /resources folder and I have built versions of the same file in my /public or /storage folder. I would like to keep my repository clean and without any duplication. Also this allows me to swap out any images without having to recompile my project.

Do you know about a workaround?

1 like
jegardiner's avatar

@xingredient I had the same problem as you describe when I upgraded my Statamic (a Laravel based CMS) project to use Vite. As Vite was referring to static assets in /public differently between development and production, because of the differing project root.

Using the following configuration file, to configure dev and production differently, seems to have solved the problem for me:

import laravel from 'laravel-vite-plugin'
import { defineConfig } from 'vite'

var config = {
    plugins: [
        laravel({
            input: [
                'resources/css/site.css',
                'resources/js/site.js',
            ],
        }),
    ],
    build: {
        assetsDir: '',
    }
}

export default defineConfig(({command, mode, ssrBuild}) => {
    if (command === 'serve') {
        config.publicDir = 'public';
        config.build = {
            assetsDir: '',
            copyPublicDir: false,
            emptyOutDir: true,
        };
    }

    return config;
});

If you try this, please let me know how you get on!

4 likes
Xanger's avatar

@jegardiner Hi your answer really helped me a lot, But I have encountered a problem and I would rather write here than open a new message.... (better to have one discussion and complete than to have 20 with incomplete chunks...).

Vite correctly generated the files for me in:

public/build/manifest.json       0.36 kB │ gzip:  0.15 kB
public/build/app-5229ad1e.css  155.98 kB │ gzip: 22.17 kB
public/build/app-c08bcf01.js    29.03 kB │ gzip: 11.59 kB

but in blade i have:

@vite(['resources/js/app.js'])

when I go to view the page I have:

<script type="module" src="http://[::1]:5175/@vite/client" data-navigate-track="reload"></script>
<script type="module" src="http://[::1]:5175/resources/js/app.js" data-navigate-track="reload"></script>

How do I get the blade to get the correct files?

shamaseen's avatar

I needed to make a proxy to make it work:

server: {
        proxy: {
            '^/assets/.*': {
                target: 'localhost',
            }
        }
    }

Please or to participate in this conversation.