Skip to content

Modern Image Formats: verify AVIF output with client side media uploads, and reflect it on the settings screen #2662

Open

Description

@adamsilverstein

Client side media processing landed in the editor for 7.1, so I want to make sure Modern Image Formats plays nicely with it before people start hitting this in the wild. Right now I think the plugin assumes the server does all the encoding. In fact we can let the browser handle the encoding for editor uploads, which means AVIF can be produced even on a host that does not support it server side. The plugin should reflect that in the settings screen and in the output format filter. One challenge is the in 7.1 the browser side is only active in the editor.

I asked Claude to dig through the code for this one, here is what it found:

Description

With client side media processing, the browser encodes the modern format image before it is ever uploaded, so the server's own AVIF support is no longer the thing that decides whether AVIF is possible. Modern Image Formats still treats it that way in three places, which means a site on a host without AVIF encoding will silently get WebP (or nothing) even when the browser could have produced AVIF.

The client picks its target format from the image_editor_output_format filter, surfaced to the editor through the image_output_format REST field on attachments:

https://github.com/WordPress/gutenberg/blob/03bab58806377943695c08f029dabc9cbad12b14/lib/media/class-gutenberg-rest-attachments-controller.php#L609-L625

Modern Image Formats hooks that filter, but only maps a source type to AVIF when the server's image editor reports it can encode AVIF:

// Find the first supported mime type by the image editor to use it as the default one.
foreach ( $valid_mime_transforms[ $mime_type ] as $target_mime ) {
if ( wp_image_editor_supports( array( 'mime_type' => $target_mime ) ) ) {
$output_format[ $mime_type ] = $target_mime;
break;
}
}

The chosen output format is also downgraded to WebP up front for the same reason:

$output_format = webp_uploads_mime_type_supported( 'image/avif' ) ? webp_uploads_get_image_output_format() : 'webp';

And the settings screen disables the AVIF option outright, telling the user to contact their host:

<option value="webp"<?php selected( 'webp', $selected ); ?><?php disabled( ! $webp_supported ); ?>><?php esc_html_e( 'WebP', 'webp-uploads' ); ?></option>
<option value="avif"<?php selected( 'avif', $selected ); ?><?php disabled( ! $avif_fully_supported ); ?>><?php esc_html_e( 'AVIF', 'webp-uploads' ); ?></option>
</select>
<label for="perflab_modern_image_format">
<?php esc_html_e( 'Generate images in this format', 'webp-uploads' ); ?>
</label>
<p class="description" id="perflab_modern_image_format_description">
<?php esc_html_e( 'Select the format to use when generating new images from uploaded images.', 'webp-uploads' ); ?>
<?php esc_html_e( 'Generated images may be discarded if the file in the modern format is larger than the originally uploaded image.', 'webp-uploads' ); ?>
</p>
<?php if ( ! $avif_supported ) : ?>
<br>
<div class="notice notice-warning inline">
<p><b><?php esc_html_e( 'AVIF support is not available.', 'webp-uploads' ); ?></b></p>
<p><?php esc_html_e( 'AVIF support can only be enabled by your hosting provider, so contact them for more information.', 'webp-uploads' ); ?></p>
</div>
<?php elseif ( ! $avif_transparency_supported ) : ?>
<br>
<div class="notice notice-warning inline">

Note that webp_uploads_mime_type_supported( 'image/avif' ) additionally requires transparent AVIF support, which is an ImageMagick version check. That check is about the server's encoder and has no bearing on what the browser can produce.

What to verify

  1. Upload a JPEG or PNG in the block editor on a site where client side media processing is active, with the output format set to AVIF, and confirm the resulting attachment is AVIF.
  2. Repeat on a server where the image editor cannot encode AVIF. Current expectation is that the client falls back to WebP or the original format, even though the browser could have done AVIF.
  3. Confirm what happens to the "Output fallback images" and "Generate all fallback image sizes" settings when the client produces the sub-sizes. Are the fallback JPEG/PNG sizes still generated, and by whom?
  4. Confirm the <picture> element output still has the fallback sources it expects for client side uploaded attachments.
  5. Check that the sub-size sideload and finalize path records the same sources metadata the plugin relies on for content filtering and for cleanup on delete.

Settings screen

On a browser that can do the transforms, the AVIF and WebP options should not be gated on server capabilities at all, since the encoding happens client side. The details text next to the setting should instead tell the user where the transform will work, which for 7.1 means editor uploads only, with the media library following in 7.2.

Worth keeping in mind that the browser side is a runtime check, not a static one. Client side processing needs WebAssembly, SharedArrayBuffer (so cross origin isolation headers have to be in place), Web Workers, and it opts out on low memory devices, low core counts, and slow or data saver connections:

https://github.com/WordPress/gutenberg/blob/trunk/packages/upload-media/src/feature-detection.ts

Since options-media.php is rendered server side, the page cannot know the answer at render time. The detection would have to run in JS on the settings screen and adjust the notices, similar to how the fallback size and picture element fields already toggle themselves.

A rough shape for the four cases:

Server encodes AVIF Browser can process What the user should see
yes yes AVIF selectable, no notice
yes no AVIF selectable, note that uploads are converted on the server
no yes AVIF selectable, note that editor uploads are converted in the browser and that other upload paths will fall back until 7.2
no no current "AVIF support is not available" notice

Notes

  • For the 7.1 window, it is clearer to say "editor client-side uploads only" in the description text

Related

AI Use

Description written with 🤖 Claude Code.

Activity

  1. moved this to Not Started/Backlog 📆 in WP Performance Ongoingon Sep 2, 2026
  2. jonahwhite115 commented on Sep 26, 2026

    @jonahwhite115

    Since the image_editor_output_format filter currently relies on server-side capabilities, we need to extend it to check for client-side support in the Gutenberg REST controller before defaulting back to WebP. Does the current implementation of the REST field allow us to distinguish between editor-initiated uploads and traditional media library uploads to apply this logic conditionally?

  3. adamsilverstein commented on Oct 23, 2026

    @adamsilverstein
    MemberAuthor

    6. Since the image_editor_output_format filter currently relies on server-side capabilities, we need to extend it to check for client-side support in the Gutenberg REST controller before defaulting back to WebP.

    I think the current client side media processing honors image_editor_output_format, as long as the browser session supports client side media. maybe the settings can note this instead of trying to detect the capability which could depend on the browser.

    Does the current implementation of the REST field allow us to distinguish between editor-initiated uploads and traditional media library uploads to apply this logic conditionally?

    If I understand the question correctly - yes, we can distinguish regular uploads with client side media initiated uploads and sideloads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Needs DiscussionAnything that needs a discussion/agreement[Plugin] Modern Image FormatsFormerly WebP Uploads [slug: webp-uploads][Type] EnhancementA suggestion for improvement of an existing feature

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions