-
-
Save uhop/9177153 to your computer and use it in GitHub Desktop.
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; | |
} | |
} | |
} |
The corresponding blog post.
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:
- Removed the
map
directive entirely - 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.
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:
- Removed the
map
directive entirely- 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 themap
directive in theserver
block.) This might make it possible to touch fewernginx
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 :)
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
Since you are using the regex on the rewrite, just look at what's actually is doing.
You can just do
rewrite (.*).2 $1.webp break;
This one seems greedy to me, didn't test it, but as well you can do:
rewrite /^(.*?)(png|jpg)$ $2.webp break;
So you can work with the regex groups.
@GariStar I am not sure your approach is correct as is:
- I am advocating against using
rewrite
. See the referenced blog post. - The gist has no rewrites.
- Your rewrite expression will be triggered on files like
nopng
, because it misses a dot in it. And it has some other minor problems.- But I do understand your point.
The reason why in my original code I add a suffix instead of manipulating names is actually simple: because I use webp
for png
and jpg
removing the original extensions opens up for a potential name clash. Compare:
image.png
⇒image.png.webp
image.jpg
⇒image.jpg.webp
with:
image.png
⇒image.webp
image.jpg
⇒image.webp
I create .webp
files statically using a utility, I don't want to deal with possible overwrites.
On top of that my actual code (not the toy one in the example) can serve multiple compressions:
brotli
,zopfli
, andgzip
for text files + original uncompressed files, if the precompressed versions are missingwebp
,zopflipng
, andpng
forpng
-style imageswebp
,guetzli
, andjpg
forjpg
-style images
Nowadays I am considering adding avif to the list.
That's why a name manipulation is not a priority to me.
If it is important it is possible not only update file names but serve files from:
- Different folders.
- Different domains (e.g., different AWS buckets).
Doing that will help with potential name clashes as well.
@uhop
I create .webp files statically using a utility, I don't want to deal with possible overwrites.
If you serving a WordPress site, you may use Warp iMagick plugin with your nginx configuration.
Can I use this without .webp files?
@h2kyaw You can. See the comments above explaining my approach. But you can obviously update the recipe to suit your needs.
This sample config is copied from grunt-tight-sprite's Recipe: serve WebP with nginx conditionally.