LaraNewDev's avatar

CORS policy blocks CSS and JS from vite server using Laragon

Dear all,

I have a working app that used mix. I migrated it to vite and worked perfectly fine. However, I installed this application in another PC and FE assets are blocked by CORS policy. Web application is shown without the assets that should come from Vite server. I see unstyled and static HTML. Browser console output indicates that CORS policy is blocking them. I am aware that this, or similar issues have been arised before, but not using Laragon as server ecosystem. Posibily this is not specifically related to Laragon, but I mention it just in case. I have tried with 2 browsers (firefox, chrome) without success. If I have this working in one PC, but failing in another, where should I begin looking at?

I add some info that may be useful: vite.config.js:

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

export default defineConfig({
    server: {
        hmr: {
            host: 'localhost',
        },
    },
    plugins: [
        laravel([
            'resources/css/main.css',
            'resources/css/katex.min.css',
            'resources/js/app.js',
        ]),
    ],
});

composer.json:

"require": {
        "php": "^8.0",
        "akaunting/laravel-language": "^1.0",
        "cyrildewit/eloquent-viewable": "^6.0.2",
        "doctrine/dbal": "^2.12",
        "laravel/framework": "^9.23",
        "laravel/tinker": "^2.0",
        "laravel/ui": "^4.0",
        "livewire/livewire": "^2.8",
        "qcod/laravel-gamify": "^1.0",
        "spatie/laravel-collection-macros": "^7.9.3",
        "spatie/laravel-honeypot": "^4.1",
        "spatie/laravel-medialibrary": "^10.0"
    },
    "require-dev": {
        "barryvdh/laravel-debugbar": "^3.3",
        "spatie/laravel-ignition": "^1.0",
        "fzaninotto/faker": "^1.9.1",
        "mockery/mockery": "^1.3.1",
        "nunomaduro/collision": "^6.1",
        "phpunit/phpunit": "^9.3",
        "guzzlehttp/guzzle": "^7.0.1"
    },

package.json:

    "devDependencies": {
        "@tailwindcss/typography": "^0.5.2",
        "autoprefixer": "^10.4.4",
        "axios": "^0.25",
        "bootstrap": "^4.0.0",
        "cross-env": "^5.1",
        "jquery": "^3.5.1",
        "laravel-vite-plugin": "^0.5.0",
        "lodash": "^4.17.20",
        "popper.js": "^1.12",
        "postcss": "^8.4.12",
        "tailwindcss": "^3.0.23",
        "vite": "^3.0.2"
    },
    "dependencies": {
        "alpinejs": "^3.7.1",
        "chart.js": "^3.7.0",
        "daisyui": "^2.24.0",
        "katex": "^0.16.0",
        "mathjs": "^10.6.4"
    }

Vite directive at :

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

hot file content

http://localhost:5173

Thanks for the support

0 likes
12 replies
LaraNewDev's avatar

Hello, yes, but sadly without knowing what was failing. I updated to a different version of node and NPM. Then it worked. What bothers me the most is that after doing some NPM package updates it stoped working again. Did the same, switched to different NPM version and it was fine again...

colbyalbo's avatar

I'm up against the exact same issue, when running HTTPS using Laragon. Only when the using the HMR does CORS block the assets, because they are being served from a different origin, localhost:5173. (when you run build, it's fine b/c the assets are within the same origin)

I'm still searching for a solution, seems that similar issues have been encountered by those using Sail/Docker/WSL setups on Windows.

If i figure this out, i'll post it here!

my vite.config.js

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

const host = 'myapp.test';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js',],
            refresh: true,
        }),
        {
            name: 'blade',
            handleHotUpdate({ file, server }) {
                if (file.endsWith('.blade.php')) {
                    server.ws.send({
                        type: 'full-reload',
                        path: '*',
                    });
                }
            },
        }
    ],
    server: {
        host,
        hmr:{ host },
        https: {
            key: fs.readFileSync('C:/laragon/etc/ssl/laragon.key'),
            cert: fs.readFileSync('C:/laragon/etc/ssl/laragon.crt'),
        }
    },
});
colbyalbo's avatar

@laranewdev @andreich1980

Okay , finally got this working using Laragon with SSL while running vite with HMR (npm run dev). Looks like the only thing that's needed is the https config block AND setting the "ASSET_URL" environment variable in the .env file (which is what I was missing).

my revised vite.config.js

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

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js',],
            refresh: true,
        }),
        {
            name: 'blade',
            handleHotUpdate({ file, server }) {
                if (file.endsWith('.blade.php')) {
                    server.ws.send({
                        type: 'full-reload',
                        path: '*',
                    });
                }
            },
        }
    ],
    server: {
        https: {
            key: 'C:/laragon/etc/ssl/laragon.key',
            cert: 'C:/laragon/etc/ssl/laragon.crt',
        },
    },
});

AND Added this to .env

# this will make the asset url the same as the app and prevent cross origin issues when vite is serving assets from a different port on localhost  when using HMR in development
ASSET_URL="${APP_URL}"

Hope this helps

2 likes
andreich1980's avatar

@colbyalbo If we work on the project with our team, we might want extract the Laragon cert paths to the .env and only set it if the .env keys are filled.

colbyalbo's avatar

Just a quick follow up, the above setup broke the very next day. I found that there was more pieces to the puzzle. Note:

  • This may just be needed for Laragon users; I dont know about WSL/Sail/Docker setups.
  • The setup below only seems to work in Firefox. I haven't figured out Chrome, which is throwing an incompatible ssl key usage error.

Turns out the ASSET_URL environment variable is not needed at all

my vite.config.js now looks like this

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

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js',],
            refresh: true,
        }),
        {
            name: 'blade',
            handleHotUpdate({ file, server }) {
                if (file.endsWith('.blade.php')) {
                    server.ws.send({
                        type: 'full-reload',
                        path: '*',
                    });
                }
            },
        }
    ],
    server: {
        https: {
            key: 'C:/laragon/etc/ssl/laragon.key',
            cert: 'C:/laragon/etc/ssl/laragon.crt',
        },
    },

});

Then, load the page and confirm the security warning (this is because laragon's SSL cert is self-signed). At this point the page loads , but the assets don't. Looking at the console, there are CORS errors regarding the HMR vite client server at- https://127.0.0.1:5173

So, if you load the vite client url into the browser in a new tab - https://127.0.0.1:5173/@vite/client You should see the same security warning, confirm it and the laravel/vite page is now allowed to load. Now you can go back to your development domain and reload it and it load, and HMR should work.

Note: if you clear you browser cache, you will have to confirm the security exceptions again for both the dev url & the vite client url

If, I figure out a workaround for chrome I'll post it here.

2 likes
LaraNewDev's avatar

Thanks @colbyalbo for picking up the topic. However, I am not entirely sure that the ultimate cause is being addressed. Why do I say this? It is because I have the app working on 2 different PCs (both with Laragon) without any HTTPS configuration. Actually, my vite.config.js is still as it was in the opening post and with this config I have had working and non-working setups in the past. We maybe see two different problems with the same sympthoms or maybe something out of our knowledge is affecting the behaviour.

It is very nice though, that your config works and I will replicate it if my setup breaks again.

nyce's avatar

I did a fair bit bit soul-searching when I came up against this error. For what it's worth, the CORS error turned out to be a total distraction from the actual cause of the problem. Can't speak for everyone's individual configs of course, but at least in my case the issue was a symptom of the problem rather than a useful indication of the cause. I eventually discovered that an update in an npm asset dependency was the source of the problem. I had to import some SCSS files in a different order.

Make sure you tune up your logging options to help you debug better!!

ArthurYdalgo's avatar

I had this problem on two different projects and I discovered that when using

  • "vite": "^4.0.0"
  • "laravel-vite-plugin": "^0.7.8"
  • "@ vitejs/plugin-react": "^3.1" (I put a space there so it wouldn't mention the laracast user "vitejs")

in my package.json, sometimes vite would be bumped up to a version higher than 4.5.5 when installing another package, which would start causing the issue. any other 4.x version after that one would trigger the issue... I just noticed that 4.5.6 was release jan 20th 2025 (16 days ago at the time of writing).

two possible fixes (both worked for me, but I went for the second one):

1 - keep "vite" at "4.5.5" in your package.json

2 - update "vite" to "^6.0" in your package.json

additionally, you might need to change at least those two packages I mentioned above. I updated them to:

  • "laravel-vite-plugin": "^1.2",
  • "@ vitejs/plugin-react": "^4.3" (I put a space there so it wouldn't mention the laracast user "vitejs")

edit: additional notes: you might to delete your package-lock.json and/or your node_modules directory before attempting another "npm install" to get the new versions

2 likes
pasteldenata's avatar

@ArthurYdalgo thank you! I was struggling not understanding why things stopped working all of the sudden... followed your recommandations (upgraded to newer versions of mentioned packages) and now I'm good to go ;)

By the way I'm not using (at)vitejs/plugin-react, so I guess it is really a pure vitejs issue (switched from ^5.0 to ^6.0 to solve the issue).

1 like
muhammedozalp's avatar

Sometimes it is just APP_URL= in the .env file. It is solving, when you add the URL with the https.

Medboubazine's avatar

You can add a header "Access-Control-Allow-Origin" to your vite.config.js

export default defineConfig({
	//...Configs
    server: {
        //....
		headers: {
        	'Access-Control-Allow-Origin': '*',
        },
    },
});

4 likes

Please or to participate in this conversation.