Laravel CORS Issue when dealing with image files inside public folder?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Laravel CORS Issue when dealing with image files inside the public folder
Dealing with Cross-Origin Resource Sharing (CORS) errors is one of the most frustrating hurdles in modern web development, especially when integrating a Single Page Application (SPA) like Vue.js with a backend framework like Laravel. When you move from serving content directly via your domain (project.test) to fetching assets from localhost:8080, the browser's security policies become much stricter.
This post dives deep into why accessing static files within the public folder can trigger these CORS errors, and how a senior developer should approach solving this problem in a Laravel environment.
Understanding the Root Cause of the CORS Problem
The error message you are seeingâAccess to fetch at '...' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is presentâtells us exactly what the browser is complaining about.
When your Vue application running on http://localhost:8080 tries to fetch an image from your Laravel server, the browser performs a security check. If the response headers from the server do not explicitly grant permission for the requesting origin (localhost:8080), the request is blocked, regardless of whether the file exists on the server itself.
The confusion arises because when you access project.test/images/file.jpeg directly in your browser (from a different context), it works fine. This is often because the direct access bypasses the complex cross-origin security checks that occur during an AJAX or fetch request initiated by another domain.
Why laravel-cors and .htaccess Might Fail for Static Files
You correctly noted that applying standard CORS middleware (like laravel-cors) might not directly solve this when dealing with static assets in the public directory, as it is primarily designed to manage API responses. Similarly, manipulating the .htaccess file while using Valet adds another layer of complexity because you are trying to inject specific header logic based on the request origin within a server configuration file that manages Laravel routing.
The fundamental issue here is not what the server serves, but how the server configures the response headers for static files requested via HTTP methods like GET.
The Recommended Solution: Serving Assets via Laravel Routes
Instead of relying on raw public file access to solve cross-origin issues, the most robust and Laravel-idiomatic solution is to intercept the request in your Laravel application. This ensures that all data deliveryâwhether it's an API response or a static assetâpasses through controlled middleware where CORS policies are explicitly managed.
Here is a step-by-step approach:
Step 1: Restructure Asset Delivery
Instead of making the image directly accessible at http://project.test/images/filename, you should create a route in your Laravel application to serve these files. This gives you full control over the response headers.
In routes/web.php:
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
Route::get('/images/{filename}', function ($filename) {
// Ensure the file exists in your public/images directory
$path = 'images/' . $filename;
if (!Storage::disk('public')->exists($path)) {
abort(404);
}
$fileContents = Storage::disk('public')->get($path);
$mimeType = Storage::disk('public')->mimeType($path);
// Return the file content with correct headers
return response($fileContents, 200, [
'Content-Type' => $mimeType,
'Access-Control-Allow-Origin' => '*', // Or specify your exact frontend domain
'Access-Control-Allow-Methods' => 'GET',
]);
})->where('filename', '[a-zA-Z0-9_-]+'); // Basic sanitization for securityStep 2: Configure CORS Globally (The Laravel Way)
Once you are handling the delivery through a controlled route, you can configure your CORS settings globally using packages or custom middleware. This is cleaner than file-level hacks. For comprehensive API and asset CORS management, exploring solutions that integrate well with the framework structureâlike those discussed on the official https://laravelcompany.com documentation regarding API designâwill be beneficial.
If you are setting up your application for external consumption, make sure your config/cors.php file is correctly configured to allow requests from your Vue development origin (http://localhost:8080).
Conclusion
Trying to patch CORS issues by modifying .htaccess files for static assets often leads to brittle solutions that break when moving between local development (Valet) and production environments. The correct approach in a Laravel application is to treat all data delivery, including static assets, as controlled endpoints. By serving images through a defined route within your Laravel application, you gain the necessary control to inject precise CORS headers, ensuring a secure, predictable, and maintainable experience for your Vue frontend.