How to access image from /storage -laravel- from SPA with vuejs
Asked Answered
W

7

11

if i put an image in "storage/app/public/img/logo.png" and execute: 

$ php artisan storage:link

How i get that logo.png in vue component?

<img src="storage/app/public/img/logo.png">

The requested it's ok (200) but that image not render, because is an SPA.

Thank you,

Whitethorn answered 19/3, 2019 at 22:10 Comment(1)
The solution is symbolic links. Check this answer. https://mcmap.net/q/790466/-laravel-5-4-storage-linkDisobedient
W
9

Well, after to do:

$ php artisan storage:link

In my component i used:

<img :src="'../storage/img/logo.png'">

thanks,

Whitethorn answered 20/3, 2019 at 17:27 Comment(2)
What's the workaround for a vuejs frontend that is built using vue-cli and is separate from the laravel backend but both served using the same domain?. eg. vuejs-frontend -> /var/html/vuejs/dist laravel-backend -> /var/html/laravel-backendNewberry
@Newberry Similar, but you need to use the full URL to a backend storage. Of course, this is a solution for a public files though. If you need private files, it is more complicated and I think there are only two options: 1. sending the files directly through API, 2. accessing the 3rd party storage like AWS bucket from the two separate apps (e.g. Laravel will store it there and Vue would load it). There may be other solution which I am not aware though...Backspace
S
5
  1. Check config/filesystems.php (ie: unmodified default):
    // If server doesn't support "making symbolic links":
    // https://medium.com/@shafiya.ariff23/how-to-store-uploaded-images-in-public-folder-in-laravel-5-8-and-display-them-on-shared-hosting-e31c7f37a737
    'public' => [
        'driver' => 'local',
        'root' => storage_path('app/public'),
        'url' => env('APP_URL').'/storage',
        'visibility' => 'public',
    ],
  1. Save an image:
   $image = $request->file('image'); // something like that
   $slug = 'some-slug-99';

   $image->storeAs(
       'examples' .'/'. $slug,
       $image->getClientOriginalName(),
       'public'
   );
  1. Create the symlink from /storage/app/public to public/storage (ie: your public html folder which makes asset() work in Laravel Blade templates, I think but don't quote me on that)
$ php artisan storage:link
  1. Place the HTML in your Vue component:
<img
    v-for="image in example.images"
    :key="image.filename"
    :src="`/storage/examples/${example.slug}/${image.filename}`"
>

Also, read the docs: https://laravel.com/docs/8.x/filesystem

Salpingitis answered 2/11, 2020 at 3:52 Comment(0)
G
2

When you use the storage:link command, you create a symbolic link between your storage/app/public folder and your public/storage folder.

So now you can find your files at the url $BASE_URL/storage/img/logo.png.

I recommend you to use the asset helper function inside your blade template:

<img src="{{ asset('storage/img/logo.png' }}">

NOTE: be sure to set the proper file permissions on the folder or you get an Unauthorized error when trying to access it.

Graham answered 20/3, 2019 at 8:44 Comment(2)
This is the best answer it worked for me after running php artisan storage:link then I used in my img path :src="'./storage/profile/' + member.profile_pic" where profile is my folder inside storage/app/public/profile and member.profile_pic is my image. Great THANKS!Wrennie
This only works when using blade templates. The original question was asking about accessing the images within a SPA written in Vuejs so this answer is irrelevant and answering a different questionIndra
D
1

When using php artisan storage:link you are creating a simbolic link from public/storage to storage/app/public

I'm used to use asset instead regular path: Try using src="{{ asset('storage/app/public/img/logo.png') }}

It is supposed that if you are using a SPA, when a component renders, it will make a new request to get the img

Dorcia answered 20/3, 2019 at 8:38 Comment(0)
L
1

Hope my answer will help someone, Create a symbolic link by using this command

php artisan storage:link

now use it in you vue template as following

/storage/path/to/file
Lean answered 28/7, 2020 at 12:50 Comment(1)
Great, thanks! This works!Alisaalisan
R
0

routes/web.php

For SPA application, Laravel usually render index blade for all incoming requests.

Route::get('/{any}', function () {
    return view('index');
})->where('any', '.*');

I changed this route so that all routes except "/storage/**/." locate index blade page. This way, you can both render SPA and get uploaded image.

Route::any('{all}', function () {
    return view('index');
})->where('all', '^(?!storage).*$');

I assume you have already created symlink using php artisan storage:link command.
Take a look Vue js laravel 8 routing

Resort answered 7/10, 2021 at 12:35 Comment(0)
B
0

I don't know why no one write their solution clear. In Laravel and vuejs When you store files inside laravel storage do as bellow;

  1. create a symlink by running php artisan storage:link it will create a directory inside your-project/public by the name of storage which is not actually a directory that is a link to project/storage directory, if you navigate to your-project/public you will see all the files uploaded into your storage showing here, now you cannot access your file directly from here.
  2. If you have an image stored in this location: storage/app/public/files/logo.png the path to show the image in vue a component will be /storage/files/logo.png please escape app/public parts. <b-avatar href="#" :src="'/storage/files/logo.png'"></b-avatar> I hop it help someone.
Bozuwa answered 21/8, 2022 at 9:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.