Configure NGINX to transparently serve AVIF files when supported

ShortPixel Image Optimizer has 2 native AVIF delivery methods, but sometimes neither is able to properly serve your AVIF files, especially if you have an NGINX server (which does not support .htaccess files). If this is the case for you, and you have ShortPixel properly configured to generate (not deliver) AVIF files, the best option is to use the capabilities of NGINX and transparently serve the AVIF version of your original file, if supported.

The solution is simple, albeit manual: edit the NGINX configuration files, either nginx.conf or, if you have a setup with multiple sites, the appropriate configuration file from /etc/nginx/sites-available.

Stop here! Before reading the instructions, make sure you understand the following:

  • This method does not work for websites with Cloudflare's free plan.
  • After everything is configured, your AVIF files will show up with the same URL and extension. Your browser will display image.jpg, but the image will actually be a AVIF file.
  • This solution is the version we have found to accomplish this task most successfully. If it does not work as expected or does not meet your requirements, we recommend you to get professional help from an NGINX expert. Hey, if you find something better, drop us a line too!
  • If you are using a CDN provider that is not Cloudflare, or if you have a paid plan from Cloudflare, you need to make sure it supports the Vary header and is properly configured to deliver AVIF from the same URL based on browser capabilities so that it knows (and caches and delivers accordingly) that there are 2 different files to deliver for the same URL depending on the Accept header sent by the browser.
    • Examples: bunny.net / Cloudflare
    • If you are using a CDN that does not support the Vary header, or if you do not have the technical knowledge to implement it, you should not use this solution at all, or you may end up serving AVIF images to browsers that do not support them. Instead, use one of the alternative solutions described at the end of this article.

Here are the instructions:

  1. Configure your NGINX so it is able to deliver the AVIF files: I get the message "Avif server test failed". How do I configure my web server to deliver AVIF images?

  2. Insert this block before the server directive:

    map $http_accept $avif_suffix {
        default "";
        "~*avif" ".avif";
    }
    	

    This sets the $avif_suffix if the browser has AVIF capability.

  3. Insert this block inside the server directive:

    location ~* ^(/wp-content/.+)\.(png|jpe?g)$ {
        set $base $1;
        set $avif_uri $base$avif_suffix;
        set $avif_old_uri $base.$2$avif_suffix;
        set $root "<<FULL PATH OF WP-CONTENT PARENT>>";
        root $root;
        add_header Vary Accept;
        if ( !-f $root$avif_uri ) {
            add_header X_AVIF_SP_Miss $root$avif_uri;
        }
        try_files $avif_uri $avif_old_uri $uri =404;
    }
    	

    Make sure to replace <<FULL PATH OF WP-CONTENT PARENT>> with the actual absolute path to the wp-content folder, without the folder itself. Example: /home/john/public_html/.
    The  X_AVIF_SP_Miss header is not necessary, but useful for testing - this header is set if the browser has AVIF capabilities, but no AVIF version of the image is found on disk. You can disable it later by commenting out the entire if directive.

  4. Disable ShortPixel's native delivery method. Go to Settings > ShortPixel > Advanced and uncheck the box "Deliver the next generation versions of the images in the front-end":

Example (Plesk)

If you use Plesk to manage your NGINX server, you can follow these instructions.

  1. Connect to the Plesk server via SSH.
  2. Create the /etc/nginx/conf.d/avif.conf file by entering the following command:
    touch /etc/nginx/conf.d/avif.conf
    	
  3. Open the avif.conf file in a text editor (e.g. vi editor) and add the following content:
    map $http_accept $avif_suffix {
      default "";
      "~*avif" ".avif";
    }
    	
  4. Save the changes and close the file.
  5. Log in to Plesk and go to Domains > yourdomain.com > Hosting & DNS > Apache & nginx settings.

  6. Paste the following code snippet into the Additional nginx directives field. Don't forget to replace YOUR_DOMAIN with your actual domain name (without www or https://):

    location ~* ^(/wp-content/.+)\.(png|jpe?g)$ {
      set $base $1;
      set $avif_uri $base$avif_suffix;
      set $avif_old_uri $base.$2$avif_suffix;
      set $root "/var/www/vhosts/YOUR_DOMAIN/httpdocs/";
      root $root;
      add_header Vary Accept;
      if ( !-f $root$avif_uri ) {
        add_header X_AVIF_SP_Miss $root$avif_uri;
      }
      try_files $avif_uri $avif_old_uri $uri =404;
    }
    	

  7. Go back to your SSH connection and enter the following command to restart the nginx service and apply the changes:

    service nginx restart
    	

Alternatives

If you cannot use this method, you should try an alternative solution for AVIF image delivery:

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us