LestevMisha's avatar

The most convenient way to import an image

Hello Forum,

I am Michael, I worked with Laravel and Livewire and stumbled upon the Vite. I like the way it is intertwined with Laravel, but while studying I found that Vite has their own method to manage images (via Vite::asset), can you help me to answer following questions. What is the difference between (meaning what lies under the hood) URL::asset("images/sample.png") and Vite::asset("resources/images/sample.png")? What would be the most convenient, cheapest and fast way to import an image?

0 likes
8 replies
martinbean's avatar

@LestevMisha If a Blade template, then the image needs to be publicly accessible. So if it’s static images (i.e. images that make up part of your website’s design: logos, backgrounds, etc) then they should be in your public directory and referenced with the asset_url helper:

<!-- Will reference an image store in public/images/logo.png -->
<img src="{{ asset_url('images/logo.png') }}" alt="Logo">

If it’s user-uploaded images, then you want to upload them to private storage, and server appropriately-sized thumbnails. You can either pre-generate these if you know what sizes you’ll need them, or dynamically if you want to generate many thumbnails in many different sizes.

The reason you don’t want to store and serve user-uploaded files in a publicly-accessible location is because if a user manages to upload a malicious file, then they now have a way to execute that file and your web app and the server it’s running on is now compromised. It’s also inefficient if a user uploads say, a 4 MB image thousands of pixels wide but you only need to display it in a location that’s say, 300 pixels wide.

1 like
LestevMisha's avatar

@martinbean There's no asset_url() method in laravel, I assume it was a typo. But back to the topic, I currently use URL::asset() and secure_asset() in the projects,

{{-- blade --}}
<div>
 <img src="{{ URL::asset('img/logo.png') }}" class="b-img b-img_v21">
</div>

{{-- styles --}}
@section('main-index-styles')
    <link href="{{ secure_asset('css/main/accordion.css') }}" type="text/css" rel="stylesheet">
    <link href="{{ secure_asset('styles/main/swiper.css') }}" type="text/css" rel="stylesheet">
    <link href="{{ secure_asset('css/main/circle-video.css') }}" type="text/css" rel="stylesheet">
@stop

{{-- javascript --}}
@section('main-index-script')
    <script defer src="{{ URL::asset('js/main/main.js') }}"></script>
    <script defer src="{{ URL::asset('js/main/swiper.js') }}"></script>
    <script defer src="{{ URL::asset('js/main/accordion.js') }}"></script>
    <script defer src="{{ URL::asset('js/main/circle-video.js') }}"></script>
@stop

But there's an alternative with Vite, which is,

{{-- blade --}}
<div>
 <img src="{{ Vite::asset('resources/img/logo.png') }}" class="b-img b-img_v21">
</div>

{{-- styles --}}
@section('main-index-styles')
    @vite('resources/css/main/accordion.css')
    @vite('resources/styles/main/swiper.css')
    @vite('resources/css/main/circle-video.css')
@stop

{{-- javascript --}}
@section('main-index-script')
    @vite('resources/js/main/main.js')
    @vite('resources/js/main/swiper.js')
    @vite('resources/js/main/accordion.js')
    @vite('resources/js/main/circle-video.js')
@stop

Using this approach I can create macros and optimize images and it will be done very well.

But we have at least 4 methods in laravel to do the same thing with a tidbit of a difference:

<img src="{{ asset('img/logo.png') }}" alt="Logo">
<img src="{{ secure_asset('img/logo.png') }}" alt="Logo">
<img src="{{ URL::asset('img/logo.png') }}" alt="Logo">
<img src="{{ URL::secureAsset('img/logo.png') }}" alt="Logo">

So what would be the most convenient thing to use, knowing ofc that every project is very specific and it really relies on its purpose.

I specifically refer to the regular image that can be used anywhere in the project.

martinbean's avatar

@LestevMisha Yeah, it was a typo. The helper function’s just asset (https://github.com/laravel/framework/blob/4672516314723023f61aa165acfc3b59c5cb9269/src/Illuminate/Foundation/helpers.php#L141-L153) and not “asset_url” like I erroneously posted.

You would only use Vite::asset to reference an asset outside of your public directory. Vite::asset is handy for importing things that may be included in say, NPM packages in your node_modules directory. You can’t reference files in there directly, so you would use Vite::asset to reference and use them:

<img src="{{ Vite::asset('node_modules/bootstrap-icons/bootstrap-icons.svg') }}">

But for anything within your public directory, you can just reference them using the asset helper.

You also don’t need to use secure_asset. If you configure your proxies properly, then your application will correctly detect if it’s running under HTTPS or not, and build URLs appropriately.

2 likes
Snapey's avatar

@LestevMisha I never use the asset helper and don't see the point.

<img src="/img/logo.png" alt="Logo">

using just the absolute path (with no protocol or hostname) works in almost all instances. The only time it does not work is when the site is incorrectly running the project in a subfolder.

1 like
LestevMisha's avatar

@Snapey Well, I didn't even think about using hardcoded urls. It seems that the absolute path will work just fine, but I think it might lead to some issues in the future (i. e. migrating between different environments), but thanks :), it's interesting how different devs work with laravel).

Please or to participate in this conversation.