Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Synchro's avatar

Vite generating wrong URL for CSS asset

I'm running L9 and generating JS and CSS assets during deployment. My Vite config contains this:

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js'
            ],
            refresh: true,
        }),

My app template loads the generated assets with:

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

and the build process generates a manifest.json like this:

{
  "resources/js/app.js": {
    "file": "assets/app.0fbda6ec.js",
    "src": "resources/js/app.js",
    "isEntry": true
  },
  "resources/css/app.css": {
    "file": "assets/app.78f23fbd.css",
    "src": "resources/css/app.css",
    "isEntry": true
  }
}

However, when my app loads, it refers to two URLs to load the JS and CSS assets. The JS one is correct, but the CSS one is not, so using the above manifest examples, I end up with URLs like:

build/assets/app.0fbda6ec.js
build/assets/app.1d3fb3db.css

You can see that the JS URL is correct, matching the one in the manifest, but the CSS one is not. If I re-run npm run build, the filenames remain unchanged. Given that these are both configured in a standard way, in the same place, with the same syntax, I'm mystified why this would be. What might be going astray?

0 likes
12 replies
Sinnbeck's avatar

So the hash in the css url is one thing in the manifest and another on disk?

Synchro's avatar

@Sinnbeck No, the files on disk and the manifest match, the problem is that one of the URLs generated by the @vite template directive is incorrect. I would have assumed that these URLs would both be generated from the same manifest, but apparently not. Oddly, the wrong hash does not appear anywhere in the deployed files. I'm wondering if it's cached in Redis or something?

Synchro's avatar

@Sinnbeck The view cache is already being cleared/reloaded by my deployment script (using Envoyer & Forge) like this:

php artisan migrate --force
php artisan db:seed --class=ProductionSeeder --force
php artisan horizon:terminate
php artisan storage:link
php artisan event:cache
php artisan route:cache
php artisan view:cache
php artisan config:cache

Note that this was all working fine - I've not touched Vite in several weeks, but there have been Laravel updates that may have changed it internally.

Sinnbeck's avatar

@Synchro I'll try updating to the latest when I am at my computer. Does it happen locally if you run npm run build?

Synchro's avatar

@Sinnbeck It doesn't happen locally (the asset URLs are different according to whether you run npm dev or build, but both work), but it is happening the same way on two different servers, so it must be some deployment quirk. The problem here is that I know essentially noting about Vite beyond what's in the Laravel docs, so I have no idea what happens behind that @vite tag.

Synchro's avatar

I pushed an unrelated commit (updated Nova, which does not use the host app's styles) and after the deployment it's all come back to life. While I'm happy it's now working, I don't like things that randomly break and then fix themselves without clear reasons!

Sinnbeck's avatar

@Synchro sounds like some sort of cache was fixed but not sure which. I use vite myself and deploy using ploi, but have never had any such problems

Does forge restart fpm automatically? If not, that could perhaps be a candiate for the problem

Synchro's avatar

@Sinnbeck PHP does get restarted (by envoyer) on each deploy. It needs to do that as it preloads all PHP files into the opcache, though my second server had that preloading turned off and still had the same problem. It was a strange problem - one where I can't think how I might make it happen deliberately! Thanks for your help though.

Sunday Group BV's avatar

I'm currently having the same problem. The reference of the css file is not matching the manifest, but the js file is matching.

I've tried running vite build --force, but this does not change the referenced asset in the view.

It seems the vite is referencing an asset of an older release, in my case, up to 2-3 releases ago (The project is fairly new and not public yet, so a few pushes have been done before noticing the online issue.)

I also use deploy in combination with CI/CD.

I've run manually a few different commands to clear anything I found. php artisan optimize:clear

Removing manifest.json and the build-directory in public and rerunning npm run build, does not update the incorrect reference in the HTML.

The node_modules/.vite cache directory is not created, so it's not being cached by vite itself.

Please or to participate in this conversation.