Skip to content

WebP and AVIF images in Laravel, without touching the theme ​

The heaviest thing on most pages is the pictures, and most of them are still JPEGs. A WebP of the same photo weighs about a third less, an AVIF about half. Every current browser shows WebP, and Lighthouse asks for modern image formats on almost every site it looks at.

Turning that on in a Laravel site is usually more work than it sounds. You need a copy of every size, not only the original, and a theme that asks for it in a <picture> element or by a new URL. You need a way to convert the thousands of images already uploaded without stopping the site, and old posts that link photo-300x200.jpg directly must keep working. In WordPress it is a plugin, Performance Lab's "Modern Image Formats". In kitloom it is one setting.

One choice in Settings → Media ​

Settings → Media → Image format, in both admins:

ChoiceWhat happens
As uploadedJPEG stays JPEG, PNG stays PNG, as WordPress does.
WebPNew JPEGs and PNGs get their sizes in WebP, and the image a WebP copy beside it.
AVIFThe same in AVIF: lighter still, slower to make. Offered only when the server's GD can write it; otherwise greyed, with the reason.

A PNG becomes a lossless WebP, so screenshots keep sharp text. A copy that would weigh more than the original (it happens with small, flat pictures) is not kept. GIFs and WebP uploads stay as they are. The upload itself is never replaced: the editors, downloads and the next regeneration start from it.

A new site starts in WebP. A site that already has images stays as uploaded until you choose: nothing is converted behind your back.

No theme changes ​

Every way an image reaches a page gives the file in the chosen format: the featured image, Media::url($attachment, 'large'), galleries, widgets, custom fields, the REST API's media_details. Images inserted into old posts as wp-image-123 are shown from their copies too. The page is changed as it is drawn, so the post itself stays as it was written and switching back to As uploaded serves the JPEGs again at once.

The library you already have ​

Once WebP is chosen, the settings page counts the images that have no copy yet. Convert has the queue's workers cut them again, fifty a job. Pages keep showing the old files until the last image is done; then the page cache is cleared. The JPEG sizes stay on the disk beside the copies, so a post written last year that links one still finds it.

From the console it is one command, here and now or on the queue:

bash
php artisan media:regenerate --format=webp
php artisan media:regenerate --format=webp --queue

An AI agent connected to the site can do the same for a few images with media_regenerate, and describe_site tells it which format is served and how many images wait.

Coming from WordPress ​

The files are named and recorded the way Performance Lab names and records them: photo-jpg.webp beside photo.jpg, photo-300x200-jpg.webp for a size, and every format kept listed under sources in _wp_attachment_metadata. A WordPress site that ran the plugin is served its WebP files the moment it is moved, with nothing to convert. Moving to kitloom does not undo the work the old site already did.

Lighter still ​

Media Optimizer then squeezes the files the site writes through jpegoptim, pngquant, cwebp and the like where the server has them, the lossy WebP copies included.

Watch it ​

Media settings: image sizes, WebP and the images already uploaded

Try it ​

Open a sandbox in one click, with no sign-up: Filament or Nova. What the server needs for AVIF is in the Deployment guide.

Last updated:

kitloom — modules and themes for Laravel.
Contact · Pricing · Services · License · Refunds · Privacy · Community · YouTube · [email protected]