@hellencharless54 I imagine your hosting provider will let you create symlinks via their admin panel.
Serving Storage Files on Shared Hosting Without Symlink
Hi everyone,
I’m running into a challenge on a shared hosting environment while developing an ad marketplace in Laravel. Everything works perfectly on localhost, but on the live server, images uploaded via Livewire (storage/app/public/ads/content) are not appearing in Blade templates.
Oddly, .AVIF images work in generated previews, but .JPG and .PNG do not. Standard asset('storage/...') calls return broken links across the site. Running php artisan storage:link fails because my host restricts symlink(), giving a 500 Server Error.
I tried updating APP_URL and converting images to Base64, which works for previews, but the rest of the website still doesn’t display images.
It feels a lot like a Letter Boxed puzzle: the pieces (images) are all there in storage, but the usual paths to connect them to the public interface are blocked.
What I’ve Tried / Possible Workarounds:
Serve via a route/controller
Route::get('storage/ads/content/{filename}', function ($filename) { $path = storage_path('app/public/ads/content/' . $filename); if (!file_exists($path)) abort(404); $file = file_get_contents($path); $type = mime_content_type($path); return response($file, 200)->header("Content-Type", $type); });
Then in Blade:
Base64 encoding fallback Works for previews but can bloat page size for large images.
Manual copy to public folder
cp -r storage/app/public/ads public/ads
Then use asset('ads/content/'.$imageName) in Blade.
My questions for the Laracasts community:
Has anyone found a robust way to serve storage files on shared hosting without symlinks?
Any tips to make asset() point to the physical storage path automatically?
Thanks in advance! Would love to hear if others have solved this “Letter Boxed-style” storage puzzle on restricted hosts.
Please or to participate in this conversation.