How to Use Next-Gen Images With WordPress

#
By Mike Davey, Senior Editor

Improving the Core Web Vitals for your WordPress site is one of the best ways to boost its rank in Google. Serving “next-gen images” is one of the more frequent recommendations for getting those scores up, as fast loading images means users spend less time waiting for pages to load. In this article, we’ll discuss how to use AVIF and other next-gen image formats with WordPress, even if they aren’t natively supported.

There are four steps to using next-gen image formats with WordPress:

  1. Register the image’s MIME type with WordPress
  2. Get the correct dimensions and metadata
  3. Use WordPress hooks to automatically generate sub-sizes
  4. Serve fallback images to unsupported browsers

What is AVIF?

The AV1 Image File Format (AVIF) is an encoding based on the open-source AV1 video codec, AVIF aims to address various use cases for raster images on the web, including GIF-like animation, PNG-like transparency, and improved perceptual quality at smaller file sizes than JPEG or WebP. We’re using AVIF as an example of a next-gen image format, but the steps below should work for adding any image format to WordPress.

This is important, because WordPress support for AVIF files is practically right around the corner. It seems likely we’re going to see it in WordPress 6.5, currently scheduled for release on March 26, 2024. UPDATE: WordPress 6.5 will definitely include AVIF support.

Browser Support

AVIF is already widely supported by major browsers. Its biggest competitor, JPEG XL, is usually considered to offer more features than AVIF, but doesn’t enjoy the same level of browser support.

Data on support for the avif feature across the major browsers from caniuse.com

“Widely supported” isn’t the same thing as “universally supported,” so it’s best to consider incorporating fallback options for browsers with limited AVIF support.

How to Use Next-Gen Image Formats With WordPress

The first step in using any next-gen image format is getting WordPress to recognize that it is an image. This can be accomplished by adding in some code snippets, either in a child theme’s functions.php file or by including it in a customization plugin.

WordPress uses MIME types to determine which files can be uploaded to the Media Library and used in posts. If the file’s MIME type is not in the list, WordPress will not allow it to be uploaded.

AVIF image files in the WordPress Media Library uploader. The files are greyed out, indicating they are not recognized as Media formats.

The snippet below adds a filter to the WordPress upload_mimes hook, which is used to validate the MIME type and extensions of uploaded files.

// Add AVIF image support to WordPress

add_filter( 'upload_mimes', 'filter_allowed_mimes_avif', 1000, 1 );
function filter_allowed_mimes_avif( $mime_types ) {
   $mime_types['avif'] = 'image/avif';
   return $mime_types;
}

This isn’t specific to AVIF files. The code above should allow you to add any next-gen image format to WordPress by swapping out all instances of avif for the new MIME type’s file extension.

WordPress should recognize AVIF files as valid Media Library uploads at this point. You can even use them in posts and pages, but you’ll be limited to using them at full size…and WordPress won’t be able to tell you what the dimensions actually are. This is because WordPress uses the PHP getimagesize() function to read image dimensions so it can generate metadata for the image, but PHP versions prior to 8.2 don’t return the right dimensions for AVIF images. Click Edit Image in the Media Library, and you can see that WordPress doesn’t seem to know anything about it.

The attachment details for a recently uploaded AVIF File. The page is blank, showing that WordPress has no metadata on this file.

Getting Correct Dimensions for Next-Gen Images

Now that WordPress recognizes the file format, the next step is getting it to acknowledge the image’s dimensions. The snippet below uses the imagecreatefromavif function to create an image resource from the AVIF file, and then uses the imagesx and imagesy functions to get the width and height of the image. We then destroy the image resource using imagedestroy, and return the generated metadata to WordPress.

// Get correct dimensions for AVIF images
add_filter( 'wp_generate_attachment_metadata', 'avif_image_metadata', 1, 3 );
function avif_image_metadata( $metadata, $attachment_id, $context ) {
    if ( empty( $metadata ) ) {
        return $metadata;
    }

    $attachment_post = get_post( $attachment_id );
    if ( ! $attachment_post || is_wp_error( $attachment_post ) ) {
        return $metadata;
    }

    if ( 'image/avif' !== $attachment_post->post_mime_type ) {
        return $metadata;
    }

    if ( ( ! empty( $metadata['width'] ) && ( 0 !== $metadata['width'] ) ) && ( ! empty( $metadata['height'] ) && 0 !== $metadata['height'] ) ) {
        return $metadata;
    }

    $file = get_attached_file( $attachment_id );
    if ( ! $file ) {
        return $metadata;
    }

    if ( empty( $metadata['width'] ) ) {
        $metadata['width'] = 0;
    }

    if ( empty( $metadata['height'] ) ) {
        $metadata['height'] = 0;
    }

    if ( empty( $metadata['file'] ) ) {
        $metadata['file'] = _wp_relative_upload_path( $file );
    }

    if ( empty( $metadata['sizes'] ) ) {
        $metadata['sizes'] = array();
    }

    // Create an image resource from the AVIF file
    $image = imagecreatefromavif( $file );

    // Get the width and height of the image
    $metadata['width']  = imagesx( $image );
    $metadata['height'] = imagesy( $image );

    // Destroy the image resource
    imagedestroy( $image );

    return $metadata;
}

Click on Edit Image in the Media Library again, and you’ll see that WordPress can actually give us some information. Clicking on Scale will reveal the image’s dimensions, but something is still missing: the actual image!

Another view of the image's attachment details. WordPress can now access some of the image's metadata, such as dimensions, but the image itself is still not visible in the editor.

WordPress automatically generates sub-sizes for image uploads, but that isn’t being done here. Using next-gen image formats like AVIF also requires that you register the new format with the WordPress sub-size image generation process and make sure the image is visible in the editor.

Generating Sub-Sizes for Next-Gen Image Formats

WordPress has all the required hooks for generating image sub-sizes. Adding some filters to these hooks will allow WordPress to automatically generate sub-sized versions of AVIF or other next-gen formats.

The code snippet below adds filters to the getimagesize_mimes_to_exts hook, used to map image file extensions to their corresponding MIME types, the mime_types hook, used to map MIME types to their corresponding file extensions, and the file_is_displayable_image hook, used to determine whether an image file is displayable in the WordPress media library.

// Add AVIF image extension to WordPress
add_filter( 'getimagesize_mimes_to_exts', 'add_avif_file_extension', 1000, 1 );
function add_avif_file_extension( $mime_to_exts ) {
    $mime_to_exts['image/avif'] = 'avif';
    return $mime_to_exts;
}

// Add AVIF image type to WordPress
add_filter( 'mime_types', 'add_avif_mime_type', 1000, 1 );
function add_avif_mime_type( $mimes ) {
    $mimes['avif'] = 'image/avif';
    return $mimes;
}

// Display AVIF images
add_filter( 'file_is_displayable_image', 'is_avif_image_displayable', 1000, 2 );
function is_avif_image_displayable( $result, $path ) {
    if ( str_ends_with( $path, '.avif' ) ) {
        return true;
    }

    return $result;
}

Success! The image appears in the editor and WordPress generates sub-sized images as usual. Note that this will not create sub-sizes for AVIF images uploaded earlier, only new uploads.

Inserting an AVIF image into a post in WordPress, with correct sub-sizes being generated.

Serving Fallback Images to Unsupported Browsers

The final step is to leverage the HTML <picture> tag to conditionally display AVIF images based on browser capabilities.

The following code demonstrates how to implement conditional serving of AVIF images using the <picture> tag:

<picture>
   <source srcset="path/to/your/image.avif" type="image/avif"> <!-- specify path to AVIF image -->
   <source srcset="path/to/your/fallback.jpg" type="image/jpeg"><!-- specify path to JPEG fallback image -->
   <img src="path/to/your/default.png" alt="" /><!-- specify path to PNG default image -->
</picture>

The order of source elements matters. Browsers try to load sources until finding one that works. If no suitable source is found, the <img> element loads the default image specified at the end.

Wrapping Up

At this point, you should be able to serve not only AVIF files, but any next-gen image formats the future brings us.

Are you already serving AVIF images to your users? Did you use a method like this, or a plugin? Let us know in the comments.

About the Author

Mike Davey Senior Editor

Mike is an editor and writer based in Hamilton, Ontario, with an extensive background in business-to-business communications and marketing. His hobbies include reading, writing, and wrangling his four children.