Magento 2 with Nginx and Varnish - How to serve webp images

When the map is defined like:

map $http_accept $webp_suffix {
    default       "";
    "~image/webp" ".webp";
}

And when the try_files is:

try_files $uri$webp_suffix $uri$webp_suffix/ /get.php$args;

It means that when request URI is /media/image.jpg, nginx will look for image.jpg.webp if user's HTTP Accept header contains image/webp.

So, you need to append the .webp extension to all your image file names, instead of replacing the extension.

Edit:

For this to work on any caching server beyond original server, the cache needs to cache different versions of the URL.

To accomplish this, one needs to add

add_header Vary Accept;

to nginx configuration. This tells the upstream cache that it should store different of the URL based on user's Accept header.

So, in your case, Varnish should be configured to obey the Accept header.

Cloudflare is another problem. It does not support Vary: Accept header at all, so this approach of serving WebP images does not work with Cloudflare out of the box.

It can be worked around by adding a Cloudflare worker, which extracts the Accept header from the requests, and defines cache keys based on it.