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

unknownUser17's avatar

Laravel Image not showing on production

I am hosting my project on Hostinger and have created a symlink link from public/storage to storage/app/public, the uploaded images are stored in storage/app/public as well.

I access the image using

{{ asset( 'storage/' . $data->image ) }}

in my blade file, but the images did not display on my website.

I have tried this and it returns error 404. https://www.thehawkermarketplace.com/storage/products/May2021/CE6h3zO79QHBBiyyhL8r.jpg

This is my app directories:

https://i.imgur.com/rff2vW4.png

How should I display the image?

0 likes
33 replies
unknownUser17's avatar

The symlink has already been created from public/storage to storage/app/public

lrwxrwxrwx 1 u398449571 o53367030 78 May 26 06:23 storage -> /path/to/thehawkermarketplace.com/thehawker/storage/app/public

'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
        ],
'links' => [
    public_path('storage') => storage_path('app/public'),
],

I have tried many ways to display the image but still not showing.

SilenceBringer's avatar

@monicaa something wrong with your urls. for example, they have in url /storage/app/public/products/..., while it should be just /storage/products (app/public added in symlink). can you try one of the urls without /app/public in browser to check if it works?

If it is: remove /app/public from image urls

SilenceBringer's avatar

@monicaa can you provide 2 strings for 1 of your files:

  1. Url which requested in the browser for this file
  2. Full real path with the name of the real file
unknownUser17's avatar

Do you mean this?

Request URL:

https://thehawkermarketplace.com/storage/products/May2021/J4rKot7MIIbVxu9hNXeC.jpg 

This is my website but all the uploaded images from public storage won't display

https://www.thehawkermarketplace.com

Btw I am using Laravel Voyager for my admin panel.

codi's avatar

@unknownUser17

First off right click on the image space on your site and see what the exact URL is that the script is looking at and then check to see what the actual URL is that it should be looking at, then correct it as seen below.

  1. You must show the exact URL in your config filesystem.php file for example:- 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'users', 'throw' => false, ],

  2. You also must show the exact URL in your .env file for example:- APP_URL=http://localhost/ybiz/public

amirkamizi's avatar

first of all what does $data->image print?

I think I had a similar issue in a project. for images when your route name is the same name as a folder that exists in your server this happens. so for files rather than checking the file URL tries to get files from that folder.

honestly, I didn't know about this thing until I changed my routes to something else and it started to work. I don't know why is that but maybe you're facing the same issue. change the route to something that doesn't have a folder with similar name on the server.

unknownUser17's avatar

$data->image refers to my product's image, the image path is correct and it is stored and can be shown in the storage/app/public

My routes name is all with period like product.index.

amirkamizi's avatar

I didn't mean the route name. sorry if I didn't explain clearly. I mean since your route starts with storage/image_path and there is a folder in the server named "storage", sometimes it causes this kindof issues. if your URL was something like /exmaple_url/image_path I think the issue might get resolved.

unknownUser17's avatar

@amirkamizi I just changed my config/filesystems.php into

'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/uploads',
            'visibility' => 'public',
        ],

and

'links' => [
        public_path('uploads') => storage_path('app/public'),
    ],

and rename my public/storage into public/uploads, but still not working.

In my blade file,

{{ asset('uploads/'.$data->image) }}

Anything I wrong here or I lost somewhere?

amirkamizi's avatar

have you solved it yet?

if not then I found the files for one of my old projects. this is how I did it and it was working:

in the routes:

Route::get('/images/{id}', 'ImageController@show')->name('image_show');

in the controller

public function show(Request $request,$id){
$photo = \App\Image::where('id',$id)
                            ->first();
 return response()->file(storage_path('app/images/'.$photo->file_name));
}

file system in config

'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
        ],

in the storage folder inside app I have 2 folders

  • public
  • images
1 like
sr57's avatar

Hi @monicaa

Best way is to split the pb

-1 in the very beginning of your index file , before <?php write this line

<img scr='image.jpg' alt='Image'>

and put an image with name 'image.jpg' in your public directory

make sure your see your image

-2 with your app, have a look to your page html source and watch the scr= ... for your image

-2.1 make sure your image is at that place

-2.2 ww-data ha the rights to see it

-2.3 your route is correct

Snapey's avatar

check you don't have a route in web.php that will respond to /storage

your image path is returning a laravel 404 error and it should not be reaching the framework

unknownUser17's avatar

I checked already, there is no duplicate /storage in my web.php.

Snapey's avatar

you showed a route for storage... have you removed that?

1 like
unknownUser17's avatar

Yes, I removed that route already and did clear the route cache as well, but the image URL still returns 404.... Is it possible something wrong with my .htaccess?

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On
    php_flag log_errors on

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
Snapey's avatar

is it a laravel 404 or from your webserver?

BKF Dev's avatar

Could you echo this $data->image ? also show us your APP_URL value in .env file

Snapey's avatar

APP_URL is only used for CLI functions

jlrdw's avatar

@monicaa just store and use asset helper, like:

<img src="{{ asset('upload/imgcats') . '/' . $row->catpic }}" alt="" class="image">

Use your url.

2 likes
unknownUser17's avatar
unknownUser17
OP
Best Answer
Level 1

PROBLEM SOLVED

I decided to change my symlink from storage/app/public to public_html/storage(root app folder) and Yay, it works!!!

In config/filesystems.php:

'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL'),
            'visibility' => 'public',
        ],

'links' => [
        base_path('public_html/storage') => storage_path('app/public'),
    ],

In AppServiceProvider.php:

public function register()
    {
        $this->app->bind('path.public', function() {
            return realpath(base_path().'/../public_html');
        });
    }

@amirkamizi @sr57 @jlrdw @silencebringer @snapey @bkf dev Thanks, everyone!

3 likes
DenisOgwalphp's avatar

This Might be late but hope it helps some one Please go to your route/web.php file and add this code Route::get('/create-symlink', function (){ symlink(storage_path('/app/public'), public_path('storage')); echo "Symlink Created. Thanks"; }); Then after execute your website url with /create-symlink in you browser example it will show you symlink created.thanks and that will be done. This worked for me in production for images i uploaded in my blogs and were not rendering in the blade file.

drfcozapata's avatar

SOLVED

I tried all the recommendations given here and none of them worked for me.

The basic problem is that the symbolic link from 'public' to 'storage/app/public' that we do have locally does not exist. That's why you can't see the images.

I solved it via SSH. There is no need to modify any files; They all remain exactly the same as they were originally created and uploaded:

  1. Locate the path to access the SSH server of your hosting.
  2. The server is accessed from your computer's terminal or using Putty.
  3. Enter your SSH password.
  4. Once inside (and located in the corresponding directory), simply execute: 'php artisan storage:link'
  5. You receive the notification that the symbolic link was created.

Ready!

I hope it helps those who have not been able to solve it. It worked 100% for me with Hostinger.

1 like
Snapey's avatar

@drfcozapata using this command line magic you can also do other wonderful things like composer install and php artisan config:cache etc etc.

Without SSH access to the command line you are just playing

1 like
harimiha's avatar

are your public_html and laravel folder separated? i have the same problem but it doesnt work :(

Please or to participate in this conversation.