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

muuucho's avatar
Level 11

Display image problem in Livewire

I have problem displaying the same image file in two components, but the image only shows in one of them. I have shorten down all scripts to a minimum just to narrow down the problem but I can't find whats wrong. The paths to the image in the same blade file are for some reason different dependeing which component is rendering the view. Please have a look: Routes:

Route::get('invoices', \App\Livewire\Invoices\All::class)->name('invoices.all');
Route::get('invoices/{invoice}', \App\Livewire\Invoices\Form::class)->name('invoices.edit');

All.php

<?php
namespace App\Livewire\Invoices;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class All extends Component
{
    public function render(): View
    {
        return view('livewire.invoices.x');
    }
}

Form.php

<?php
namespace App\Livewire\Invoices;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class Form extends Component
{
    public function render(): View
    {
        return view('livewire.invoices.x');
    }
}

x.blade.php

<div>
    <embed src="storage/x.jpg"/>
</div>

When I enter http://gnirt.test/invoices in the browser the imgage is there But when I enter http://gnirt.test/invoices/3 in the browser the image is gone.

If I inspect the code and hover the image link storage/x.jpg, the paths are for some reason different.

In http://gnirt.test/invoices the path is http://gnirt.test/storage/x.jpg CORRECT

In http://gnirt.test/invoices/3 the path is: http://gnirt.test/invoices/storage/x.jpg WRONG

So, where did invoices came from and how do I get rid of it?

0 likes
8 replies
muuucho's avatar
Level 11

@migsAV Thanks.

But when I try <embed src="{{ storage_path('x.jpg') }}"/> nothing shows. But when I inspect and hover the link C:\xampp\htdocs\livewire3\storage\x.jp, it says: http://gnirt.test/invoices/C:\xampp\htdocs\livewire3\storage\x.jpg (Yes, Windows)

I have the symbolic link:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Filesystem Disk
    |--------------------------------------------------------------------------
    |
    | Here you may specify the default filesystem disk that should be used
    | by the framework. The "local" disk, as well as a variety of cloud
    | based disks are available to your application. Just store away!
    |
    */

    'default' => env('FILESYSTEM_DISK', 'local'),

    /*
    |--------------------------------------------------------------------------
    | Filesystem Disks
    |--------------------------------------------------------------------------
    |
    | Here you may configure as many filesystem "disks" as you wish, and you
    | may even configure multiple disks of the same driver. Defaults have
    | been set up for each driver as an example of the required values.
    |
    | Supported Drivers: "local", "ftp", "sftp", "s3"
    |
    */

    'disks' => [

        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
            'throw' => false,
        ],

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

        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
            'endpoint' => env('AWS_ENDPOINT'),
            'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
            'throw' => false,
        ],


    ],

    /*
    |--------------------------------------------------------------------------
    | Symbolic Links
    |--------------------------------------------------------------------------
    |
    | Here you may configure the symbolic links that will be created when the
    | `storage:link` Artisan command is executed. The array keys should be
    | the locations of the links and the values should be their targets.
    |
    */

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

];

muuucho's avatar
Level 11

This works: <embed src="{{ url('storage/x.jpg') }}"/>

migsAV's avatar

@muuucho Since you are using symbolic links, you can try

<embed src="{{ asset('storage/x.jpg') }}"/>
1 like
migsAV's avatar

@muuucho it's all up to you which one you want to use, there is no right or wrong :)

1 like
bvfi-dev's avatar

@muuucho I would also recommend you to check out secure_asset() for your live environment(If you use HTTPS). I would use asset() to generate an URL for an asset (JS/CSS files, images, documents, etc) and would use url() for routes, actions or external URLs. Although they are almost the same and url() is more general purpose, I would keep them separated to their purpose. Keep in mind asset() is used for the public folder, I found that the hard way when I had some CSS files in my private folder and needed to reference them.

1 like
LaryAI's avatar
Level 58

The issue you're encountering is due to the relative path used for the image in your x.blade.php file. When you use a relative path like storage/x.jpg, it is resolved relative to the current URL. This is why it works correctly for http://gnirt.test/invoices but not for http://gnirt.test/invoices/3.

To fix this, you should use an absolute path or a helper function to generate the correct URL for the image. Here are a couple of ways to do this:

Solution 1: Use the asset Helper Function

The asset helper function generates a URL for an asset using the current scheme of the request (HTTP or HTTPS). Update your x.blade.php file to use this helper function:

<div>
    <embed src="{{ asset('storage/x.jpg') }}"/>
</div>

Solution 2: Use the url Helper Function

Alternatively, you can use the url helper function to generate the full URL for the image:

<div>
    <embed src="{{ url('storage/x.jpg') }}"/>
</div>

Solution 3: Use a Leading Slash for Absolute Path

You can also use a leading slash to make the path absolute from the root of your domain:

<div>
    <embed src="/storage/x.jpg"/>
</div>

Summary

Any of the above solutions will ensure that the path to your image is correctly resolved regardless of the current URL. Here is the updated x.blade.php file using the asset helper function:

<div>
    <embed src="{{ asset('storage/x.jpg') }}"/>
</div>

This should resolve the issue and display the image correctly in both components.

Please or to participate in this conversation.