vinalvess's avatar

Assets added by @vite being blocked by cors

All my assets are getting loaded as expected, except the ones that I use the @vite directive to load up the vite built assets. I have a wildcard domain and each tenants access the application on a separate subdomain. The cors blocking is only happening on the subdomain level. Any ideas what could cause this issue?

0 likes
7 replies
LaryAI's avatar
Level 58

The issue you're experiencing with CORS (Cross-Origin Resource Sharing) is likely due to the fact that your assets are being served from a different subdomain than your main application. Browsers enforce CORS policies to prevent security issues, and this can cause problems when assets are loaded from different origins.

To resolve this, you need to configure your server to allow cross-origin requests for your assets. Here’s a step-by-step solution:

  1. Configure CORS in your server: Ensure that your server is set up to allow requests from your subdomains. If you're using Laravel, you can use the fruitcake/laravel-cors package to handle CORS.

  2. Install the CORS package:

    composer require fruitcake/laravel-cors
    
  3. Publish the configuration:

    php artisan vendor:publish --tag="cors"
    
  4. Configure the CORS settings: Open the config/cors.php file and configure it to allow your subdomains. You can use a wildcard for subdomains like this:

    return [
        'paths' => ['api/*', 'sanctum/csrf-cookie', 'your-vite-assets-path/*'],
        'allowed_methods' => ['*'],
        'allowed_origins' => ['*.yourdomain.com'],
        'allowed_origins_patterns' => [],
        'allowed_headers' => ['*'],
        'exposed_headers' => [],
        'max_age' => 0,
        'supports_credentials' => false,
    ];
    
  5. Ensure Vite is serving assets with the correct headers: If you're using Vite's development server, you might need to configure it to allow CORS. You can do this by adding a server configuration in your vite.config.js file:

    export default {
        server: {
            cors: {
                origin: 'http://*.yourdomain.com',
                methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
                allowedHeaders: ['Content-Type', 'Authorization'],
                credentials: true
            }
        }
    }
    
  6. Check your web server configuration: If you're using Nginx or Apache, make sure they are configured to allow CORS. For Nginx, you can add the following to your server block:

    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
    

    For Apache, you can add the following to your .htaccess file or your virtual host configuration:

    <IfModule mod_headers.c>
        Header set Access-Control-Allow-Origin "*"
        Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
        Header set Access-Control-Allow-Headers "Content-Type, Authorization"
    </IfModule>
    

By following these steps, you should be able to resolve the CORS issues and allow your Vite-built assets to be loaded correctly from your subdomains.

puklipo's avatar

Always use a path without domain.

AppServiceProvider

use Illuminate\Support\Facades\Vite;

    public function boot(): void
    {
        Vite::createAssetPathsUsing(fn (string $path) => "/$path");
    }

rendered html

default

<link rel="preload" as="style" href="http://127.0.0.1:8000/build/assets/app-***.css" />...

without domain

<link rel="preload" as="style" href="/build/assets/app-***.css" />...

Switches depending on subdomain.

1 like
vinalvess's avatar

Thanks @puklipo ! Your answer will probably solve my issue. But I'll have to upgrade my dependencies to Laravel ^10.4 , seems like it was the version this function was added to the Vite facade. I'll add another post as soon as I'm able to test your sugestion.

vinalvess's avatar

@puklipo I updated my dependencies and unfortunately it still adding the root domain to the assets, after adding the line below to the boot method of my AppServiceProvider. It seems to be always loading up the asset_url env value. It could also be because I'm behind a reverse proxy and the reverse proxy is always picking up the root domain, which I'm not sure.

...
Vite::createAssetPathsUsing(fn (string $path) => "/$path");
...
vinalvess's avatar

Never mind my previous post. Your sugestion worked! I had to clear some configuration on my reverse proxy, I was adding some headers to the request as part of the tests I ran yesterday and it was affecting the outcome. Thanks again @puklipo .

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

3 likes
michael1986's avatar

@ArthurYdalgo Thanks for Sharing Arthur, saved me a lot of time! I can confirm it has been resolved upgrading to vite 6 and laravel-vite-plugin 1.2

1 like

Please or to participate in this conversation.