When running php artisan storage:link (as per the documentation), a symlink between public/storage/ to storage/app/public is created. I realise this is by design, but it leads to some very confusing behaviour not covered by the documentation.
For example: If you storeAs a file to an avatars directory, it's stored in: storage/app/avatars and the path returned (for database storage) is: avatars/filename.jpg. This is outside the symlink. Instead we need to tell it storeAs to storage/app/public/avatars (which results in a path returned for database storage being: public/avatars/filename.jpg).
According to the documentation, all we need to do to refer to this file is asset('avatars/filename.jpg') in our code, but that doesn't work. (And neither does the string we stored: asset('public/avatars/filename.jpg').) Instead it needs to be asset('storage/avatars/filename.jpg').
Which means we need to do a str_replace('public', 'storage', asset($filename)) to make an application work as per the documentation's instructions :-/
I assume I'm doing something wrong, but this so very confusing!
It seems you're mixing up the internal storage path (avatars/filename.jpg), the real path of the file (storage/app/avatars/filename.jpg) and the public url to the file (storage/avatars/filename.jpg).
local disk when you should be using the public disk. It's the later one that the symlink is meant for.Storage::disk('public')->url('avatars/filename.jpg').Ahhhhhhhhh! Thanks so much. That was a missing piece of the puzzle.
When I storeAs with a directory and filename, (eg. avatars/filename.jpg) the file IS saved in the correct location (storage/app/public/avatars/filename.jpg) and the DB has (avatars/filename.jpg). Great.
Unfortunately when I try to load the file via {{ asset($file) }} it predictably tries the location returned by the database. Am I supposed to just manually add the required storage/ to the file location? (e.g asset('storage/'.$file))
This seems odd. Again the documentation is unclear.
Most helpful comment
It seems you're mixing up the internal storage path (
avatars/filename.jpg), the real path of the file (storage/app/avatars/filename.jpg) and the public url to the file (storage/avatars/filename.jpg).localdisk when you should be using thepublicdisk. It's the later one that the symlink is meant for.Storage::disk('public')->url('avatars/filename.jpg').