WebP Express works well on NGINX, however the UI is not streamlined NGINX yet. And of course, NGINX does not process the .htaccess files that WebP Express generates. WebP Express can be used without redirection, as it can alter HTML to use picture tags which links to the webp alternative. See “The simple way” below. Or, you can get your hands dirty and set up redirection in NGINX guided by the “The advanced way” section below.
The simple way (no redirecting rules)
The easy solution is simply to use the plugin in “CDN friendly” mode, do a bulk conversion (takes care of converting existing images), activate the “Convert on upload” option (takes care of converting new images in the media library) and enable Alter HTML (takes care of delivering webp to webp enabled browsers while still delivering the original jpeg/png to browsers not supporting webp).
PRO: Very easy to set up.
CON: Images in external CSS and images being dynamically added with javascript will not be served as webp.
CON: New new theme images will not be converted until you run a new Bulk conversion
The advanced way (creating NGINX redirecting rules)
Creating NGINX rules requires manually inserting redirection rules in the NGINX configuration file (nginx.conf or the configuration file for the site, found in /etc/nginx/sites-available). If you do not have access to do that, you will have to settle with the “simple way” described above.
There are two different approaches to achieve the redirections. The one that I recommend is based on a try_files directive. If that doesn’t work for you, you can try the alternative rules that are based on the rewrite directive. The rules are described in the next couple of sections.
For multisite on NGINX, read here
Recommended rules (using “try_files”)
Preparational step:
The rules looks for existing webp files by appending “.webp” to the URL. So for this to work, you must configure WebP Express to store the converted files like that by setting General > File extension to Append “.webp”
Preparational step 2:
From 0.25.10 and up, the configuration file has been renamed so the filename contains a “hash” of random characters (a security meassure).
You will have to find the hash by inspecting the filename of the config file.
Look in the /wp-content/webp-express/config folder for a file called something like “config.c513fe386c6b8793f9bf9ad1071d2266.json”.
The string of random characters between “config.” and “.json” is what we here call the “hash”.
You will need to use that string of characters instead of “[your-hash-here]” in the rules suggested below.
The rules:
Insert the following in the server context of your configuration file (usually found in /etc/nginx/sites-available). “The server context” refers to the part of the configuration that starts with “server {” and ends with the matching “}”.
# WebP Express rules # -------------------- location ~* ^/?wp-content/.*\.(png|jpe?g)$ { add_header Vary Accept; expires 365d; if ($http_accept !~* "webp"){ break; } try_files /wp-content/webp-express/webp-images/doc-root/$uri.webp $uri.webp /wp-content/plugins/webp-express/wod/webp-on-demand.php?xsource=x$request_filename&wp-content=wp-content&hash=[your-hash-here] ; } # Route requests for non-existing webps to the converter location ~* ^/?wp-content/.*\.(png|jpe?g)\.webp$ { try_files $uri /wp-content/plugins/webp-express/wod/webp-realizer.php?xdestination=x$request_filename&wp-content=wp-content&hash=[your-hash-here] ; } # ------------------- (WebP Express rules ends here)
BEWARE:
– Beware that when copy/pasting you might get html-encoded characters. Verify that the ampersand before “wp-content” isn’t encoded (in the last line in the try_files block)
-
Beware that the rules looks for existing webp files by appending “.webp” to the URL. So for this to work, you must configure WebP Express to store the converted files like that.
-
Beware that if you haven’t enabled png conversion, you should replace “(png|jpe?g)” with “jpe?g”.
-
Beware that if you have moved wp-content to a non-standard place, you must change accordingly. Note that you must then also change the “wp-content” parameter to the script. It expects a relative path to wp-content (from document root) and is needed so the script can find the configuration file.
-
Beware that there is a hack out there for permalinks which is based on “rewrite” (rather than the usual solution which is based on try_files). If you are using that hack to redirect missing files to index.php, you need to modify it as specified here
-
I have put in an expires statement for caching. You might want to modify or disable that.
-
The rules contains all redirections (as if you enabled all three redirection options in settings). If you do not wish to redirect to converter, remove the last line in the try_files block. If you do not wish to create webp files upon request, remove the last location block.
-
If you have configured WebP Express to store images in separate folder, you do not need the “$uri.webp” line in the first “try_files” block. But it doesn’t hurt to have it. And beware that the reverse is not true. If configured to store images in the same folder (“mingled”), you still need the line that looks for a webp in the separate folder. The reason for this is that the “mingled” only applies to the images in the upload folder – other images – such as theme images are always stored in a separate folder.
If you cannot get this to work then perhaps you need to add the following to your mime.types configuration file:
image/webp webp;
If you still cannot get it to work, you can instead try the alternative rules below.
Credits: These rules are builds upon Eugene Lazutkins solution.
Alternative rules (using “rewrite”)
In case the recommended rules does not work for you, you can try these alternative rules.
The reason I recommend the try_files approach above over these alternative rules is that it is a bit simpler and it is supposed to perform marginally better. These alternative rules are in no way inferior to the other. Choose whatever works!
Preparational step:
The rules looks for existing webp files by appending “.webp” to the URL. So for this to work, you must configure WebP Express to store the converted files like that by setting General > File extension to Append “.webp”. Also make sure that WebP Express is configured with “Destination” set to “Mingled”.
The rules:
Insert the following in the server context of your configuration file (usually found in /etc/nginx/sites-available). “The server context” refers to the part of the configuration that starts with “server {” and ends with the matching “}”.
# WebP Express rules # -------------------- location ~* ^/wp-content/.*\.(png|jpe?g)$ { add_header Vary Accept; expires 365d; } location ~* ^/wp-content/.*\.webp$ { expires 365d; if ($whattodo = AB) { add_header Vary Accept; } } if ($http_accept ~* "webp"){ set $whattodo A; } if (-f $request_filename.webp) { set $whattodo "${whattodo}B"; } if ($whattodo = AB) { rewrite ^(.*) $1.webp last; } if ($whattodo = A) { rewrite ^/wp-content/.*\.(jpe?g|png)$ /wp-content/plugins/webp-express/wod/webp-on-demand.php?xsource=x$request_filename&wp-content=wp-content&hash=[your-hash-here] break; } # ------------------- (WebP Express rules ends here)
“
BEWARE:
-
Beware that when copy/pasting you might get html-encoded characters. Verify that the ampersand before “wp-content” isn’t encoded (in the last line in the try_files block)
-
Beware that the rules looks for existing webp files by appending “.webp” to the URL. So for this to work, you must configure WebP Express to store the converted files like that.
-
Beware that if you haven’t enabled png conversion, you should replace “(png|jpe?g)” with “jpe?g”.
-
Beware that if you have moved wp-content to a non-standard place, you must change accordingly. Note that you must then also change the “wp-content” parameter to the script. It expects a relative path to wp-content (from document root) and is needed so the script can find the configuration file.
-
Beware that there is a hack out there for permalinks which is based on “rewrite” (rather than the usual solution which is based on try_files). If you are using that hack to redirect missing files to index.php, you need to modify it as specified here
-
I have put in an expires statement for caching. You might want to modify or disable that.
-
I have not set any expire on the webp-on-demand.php request. This is not needed, as the script sets this according to what you set up in WebP Express settings. Also, trying to do it would require a new location block matching webp-on-demand.php, but that would override the location block handling php files, and thus break the functionality.
-
There is no longer any reason to add “&$args” to the line begining with “/wp-content”. It was there to enable debugging a single image by appending “?debug” to the url. I however removed that functionality from webp-on-demand.php.
It is possible to put this stuff inside a location directive. However, having if directives inside location directives is considered evil. But it seems that in our case, it works. If you wish to do that, use the following rules instead:
# WebP Express rules # -------------------- location ~* ^/wp-content/.*\.(png|jpe?g)$ { add_header Vary Accept; expires 365d; if ($http_accept ~* "webp"){ set $whattodo A; } if (-f $request_filename.webp) { set $whattodo "${whattodo}B"; } if ($whattodo = AB) { rewrite ^(.*) $1.webp last; } if ($whattodo = A) { rewrite ^/wp-content/.*\.(jpe?g|png)$ /wp-content/plugins/webp-express/wod/webp-on-demand.php?xsource=x$request_filename&wp-content=wp-content&hash=[your-hash-here] last; } } location ~* ^/wp-content/.*\.webp$ { expires 365d; if ($whattodo = AB) { add_header Vary Accept; } } # ------------------- (WebP Express rules ends here)
PS: In case you only want to redirect images to the script (and not to existing), the rules becomes much simpler:
# WebP Express rules # -------------------- if ($http_accept ~* "webp"){ rewrite ^/(.*).(jpe?g|png)$ /wp-content/plugins/webp-express/wod/webp-on-demand.php?xsource=x$request_filename&wp-content=wp-content&hash=[your-hash-here] break; } # ------------------- (WebP Express rules ends here)
Discussion on this topic here
And here: https://github.com/rosell-dk/webp-express/issues/166
Here are rules if you need to replace the file extension with “.webp” rather than appending “.webp” to it: https://www.keycdn.com/support/optimus/configuration-to-deliver-webp