Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Serving WEBP with nginx conditionally.
user www-data;
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# IMPORTANT!!! Make sure that mime.types below lists WebP like that:
# image/webp webp;
include /etc/nginx/mime.types;
default_type application/octet-stream;
gzip on;
gzip_disable "msie6";
##
# Conditional variables
##
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
##
# Minimal server
##
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html;
# Make site accessible from http://localhost/ or whatever you like
server_name localhost;
location ~* ^/images/.+\.(png|jpg)$ {
root /home/www-data;
add_header Vary Accept;
try_files $uri$webp_suffix $uri =404;
}
}
}
@uhop

This comment has been minimized.

Copy link
Owner Author

uhop commented Feb 24, 2014

@uhop

This comment has been minimized.

Copy link
Owner Author

uhop commented Feb 24, 2014

The corresponding blog post.

@chrisallenlane

This comment has been minimized.

Copy link

chrisallenlane commented Jan 25, 2019

Thanks for both the gist and the blog post. They were really helpful.

One note: as far as I can tell, this can be simplified a bit. I did the following:

  1. Removed the map directive entirely
  2. Re-wrote try_files like this: try_files "${uri}.webp" $uri =404;

So now we're just doing a simple string interpolation instead of a map lookup.

This is convenient, because all of the relevant configs can now be placed within the server block. (Previously, I got errors when I deviated from what you did here and tried to put the map directive in the server block.) This might make it possible to touch fewer nginx config files than would otherwise be necessary.

It's possible that I'm overlooking something here, but as best as I can tell, this all works OK.

@lucaswdm

This comment has been minimized.

Copy link

lucaswdm commented Aug 26, 2019

Thanks for both the gist and the blog post. They were really helpful.

One note: as far as I can tell, this can be simplified a bit. I did the following:

  1. Removed the map directive entirely
  2. Re-wrote try_files like this: try_files "${uri}.webp" $uri =404;

So now we're just doing a simple string interpolation instead of a map lookup.

This is convenient, because all of the relevant configs can now be placed within the server block. (Previously, I got errors when I deviated from what you did here and tried to put the map directive in the server block.) This might make it possible to touch fewer nginx config files than would otherwise be necessary.

It's possible that I'm overlooking something here, but as best as I can tell, this all works OK.

Hi!

The problem of your conf is one:

You are now, serving webp for 100% of users. webp is only visible (or should be) on Chrome or other more recent browsers. If you try your config on a old browser, the image will show with error... That why the MAP use the variable $http_accept :)

@pmochine

This comment has been minimized.

Copy link

pmochine commented Oct 8, 2019

Btw guys, thank you! With the help of: https://serverfault.com/questions/987086/serving-webp-with-nginx-conditionally-for-laravel/987179#987179 I could make it for me better.

For example: picture.jpg => picture.webp and not picture.jpg.webp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.