These Nginx rules serve the original PNG or JPEG when a browser does not support the requested AVIF/WebP format, or when the converted file is missing.
Add the following rules inside your site’s existing server {} block, before other image regex locations. Keep your existing WordPress and PHP rules.
location ~* ^(?<flying_press_image_base>.+)\.(?<flying_press_image_format>avif|webp)$ {
expires 365d;
add_header Vary Accept always;
error_page 404 = @flying_press_image_fallback;
set $flying_press_accept "$flying_press_image_format:$http_accept";
if ($flying_press_accept !~* "^(avif:.*image/avif|webp:.*image/webp)") {
return 404;
}
try_files $uri =404;
}
location @flying_press_image_fallback {
expires 365d;
add_header Vary Accept always;
try_files $flying_press_image_base.png $flying_press_image_base.jpg $flying_press_image_base.jpeg $uri =404;
}
The original must use the same path and filename with a different extension. For example, /uploads/photo.avif falls back to photo.png, photo.jpg, then photo.jpeg, in that order.
If no original exists, an existing converted file is still served. If none of these files exists, Nginx returns 404.
The rules add Vary: Accept so caches distinguish modern images from their fallbacks, and set image browser caching to one year.
Run nginx -t, then reload Nginx after the configuration passes.
To test fallback for a browser without AVIF support, use an image that has an original PNG or JPEG:
curl -I -H 'Accept: image/jpeg' https://example.com/wp-content/uploads/photo.avif
The response should have Content-Type: image/png or image/jpeg, and Vary: Accept.
This setup works independently of page caching. To serve cached pages directly through Nginx, see Serve FlyingPress Cache Directly with Nginx.
