=== WebP Express ===
Contributors: rosell.dk
Donate link: https://wordpress.org/plugins/webp-express/#%0Ahow%20do%20i%20buy%20you%20a%20cup%20of%20coffee%3F%0A
Tags: webp, images, performance
Requires at least: 4.0
Tested up to: 5.5
Stable tag: 0.18.2
Requires PHP: 5.6
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html

Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP.

== Description ==

About 4 out of 5 F users use a browser that is able to display webp images. Yet, on most websites, they are served jpeg images, which are typically double the size of webp images for a given quality. What a waste of bandwidth! This plugin was created to help remedy that situation. With little effort, Wordpress admins can have their site serving autogenerated webp images to browsers that supports it, while still serving jpeg and png files to browsers that does not support webp.

### The image converter
The plugin uses the [WebP Convert](https://github.com/rosell-dk/webp-convert) library to convert images to webp. *WebP Convert* is able to convert images using multiple methods. There are the "local" conversion methods: `imagick`, `cwebp`, `vips`, `gd`. If none of these works on your host, there are the cloud alternatives: `ewww` (paid) or connecting to a Wordpress site where you got WebP Express installed and you enabled the "web service" functionality.

### The "Serving webp to browsers that supports it" part.

The plugin supports different ways of delivering webps to browsers that supports it:

1. By routing jpeg/png images to the corresponding webp - or to the image converter if the image hasn't been converted yet.
2. By altering the HTML, replacing image tags with *picture* tags. Missing webps are auto generated upon visit.
3. By altering the HTML, replacing image URLs so all points to webp. The replacements only being made for browsers that supports webp. Again, missing webps are auto generated upon visit.
4. In combination with *Cache Enabler*, the same as above can be achieved, but with page caching.
5. You can also deliver webp to *all* browsers and add the [webpjs](http://webpjs.appspot.com) javascript, which provides webp support for browsers that doesn't support webp natively. However, beware that the javascript doesn't support srcset attributes, which is why I haven't added that method to the plugin (yet).

The plugin implements the "WebP On Demand" solution described [here](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/webp-on-demand/webp-on-demand.md) and builds on a bunch of open source libraries (all maintained by me):
- [WebPConvert](https://github.com/rosell-dk/webp-convert): For converting images to webp
- [WebP Convert Cloud Service](https://github.com/rosell-dk/webp-convert-cloud-service): For the Web Service functionality
- [DOM Util for WebP](https://github.com/rosell-dk/dom-util-for-webp): For the Alter HTML functionality
- [Image MimeType Guesser](https://github.com/rosell-dk/image-mime-type-guesser): For detecting mime types of images.
- [HTAccess Capability Tester](https://github.com/rosell-dk/htaccess-capability-tester): For testing .htaccess capabilities in a given directory, using live tests

### Benefits
- Much faster load time for images in browsers that supports webp. The converted images are typically *less than half the size* (for jpeg), while maintaining the same quality. Bear in mind that for most web sites, images are responsible for the largest part of the waiting time.
- Better user experience (whether performance goes from terrible to bad, or from good to impressive, it is a benefit)
- Better ranking in Google searches (performance is taken into account by Google)
- Less bandwidth consumption - makes a huge difference in the parts of the world where the internet is slow and costly (you know, ~80% of the world population lives under these circumstances).
- Currently ~86% of all traffic, and ~78% of mobile browsing traffic are done with browsers supporting webp. With Apple finally on board (Safari 14.0), these numbers are bound to increase. Check current numbers on [caniuse.com](https://caniuse.com/webp)).
- It's great for the environment too! Reducing network traffic reduces electricity consumption which reduces CO2 emissions.

== Installation ==

1. Upload the plugin files to the `/wp-content/plugins/webp-express` directory, or install the plugin through the WordPress plugins screen directly.
2. Activate the plugin through the 'Plugins' screen in WordPress
3. Configure it (the plugin doesn't do anything until configured)
4. Verify that it works

### Configuring
You configure the plugin in *Settings > WebP Express*.

#### Operation modes
As sort of a main switch, you can choose between the following modes of operation:

*Varied image responses*:
WebP Express creates redirection rules for images, such that a request for a jpeg will result in a webp – but only if the request comes from a webp-enabled browser. If a webp already exists, it is served immediately. Otherwise it is converted and then served. Note that not all CDN's handles varied responses well.

*CDN friendly*:
In "CDN friendly" mode, a jpeg is always served as a jpeg. Instead of varying the image response, WebP Express alters the HTML for webp usage.

*Just redirect*:
In "just redirect" mode, WebP Express is used just for redirecting jpeg and pngs to existing webp images in the same folder. So in this mode, WebP express will not do any converting. It may be that you use another plugin for that, or that you converted the images off-line and uploaded them manually.

*Tweaked*:
Here you have all options available.

#### Conversion methods
WebP Express has a bunch of methods available for converting images: Executing cwebp binary, Gd extension, Imagick extension, ewww cloud converter and remote WebP express. Each requires *something*. In many cases, one of the conversion methods will be available. You can quickly identify which converters are working - there is a green icon next to them. Hovering conversion methods that are not working will show you what is wrong.

In case no conversion methods are working out of the box, you have several options:
- You can install this plugin on another website, which supports a local conversion method and connect to that using the "Remote WebP Express" conversion method
- You can [purchase a key](https://ewww.io/plans/) for the ewww cloud converter. They do not charge credits for webp conversions, so all you ever have to pay is the one dollar start-up fee :)
- You can set up [webp-convert-cloud-service](https://github.com/rosell-dk/webp-convert-cloud-service) on another server and connect to that. Its open source.
- You can try to meet the server requirements of cwebp, gd, imagick or gmagick. Check out [this wiki page](https://github.com/rosell-dk/webp-convert/wiki/Meeting-the-requirements-of-the-converters) on how to do that

### Quality detection of jpegs
If your server has Imagick extension or is able to execute imagemagick binary, the plugin will be able to detect the quality of a jpeg, and use that quality for the converted webp. You can tell if the quality detection is available by hovering the help icon in Conversion > Jpeg options > Quality for lossy. The last line in that help text tells you.

This auto quality has benefits over fixed quality as it ensures that each conversion are converted with an appropriate quality. Encoding low quality jpegs to high quality webps does not magically increase the visual quality so that your webp looks better than the original. But it does result in a much larger filesize than if the jpeg where converting to a webp with the same quality setting as the original.

If you do not have quality detection working, you can try one of the following:
- Install Imagick on the server (for this purpose, it is not required that it is compiled with WebP support)
- Install imagemagick on the server and grant permission for PHP to use the "exec" function.
- Use "Remote WebP Express" converter to connect to a site, that *does* have quality detection working
- If you have cwebp converter available, you can configure it to aim for a certain reduction, rather than using the quality parameter. Set this to for example 50%, or even 45%.

### Verifying that it works (in "Varied image responses" mode)
1. Make sure at least one of the conversion methods are working. It should have a green checkmark next to it.
2. If you haven't saved yet, click "Save settings". This will put redirection rules into .htaccess files in the relevant directories (typically in uploads, themes and wp-content/webp-express/webp-images, depending on the "Scope" setting)
3. I assume that you checked at least one of the checkboxes in the .htaccess rules section - otherwise you might as well change to "CDN friendly" mode. The first
4. Click the "Live test" buttons to see that the enabled rules actually are working. If they are not, it *could* be that the server needs a little time to recognize the changed rules.

The live tests are quite thorough and I recommend them over a manual test. However, it doesn't hurt to do a manual inspection too.

*Doing a manual inspection*

Note that when WebP Express is serving varied image responses, the image URLs *still points to the jpg/png*. If the URL is visited using a browser that supports webp, however, the response will be a webp image. So there is a mismatch between the file extension (the filename ends with "jpg" or "png") and the file type. But luckily, the browser does not rely on the extension to determine the file type, it only looks at the Content-Type response header.

To verify that the plugin is working (without clicking the test button), do the following:

- Open the page in a browser that supports webp, ie Google Chrome
- Right-click the page and choose "Inspect"
- Click the "Network" tab
- Reload the page
- Find a jpeg or png image in the list. In the "type" column, it should say "webp"

You can also look at the headers. When WebP Express has redirected to an existing webp, there will be a "X-WebP-Express" header with the following value: "Redirected directly to existing webp". If there isn't (and you have checked "Enable redirection to converter"), you should see a "WebP-Convert-Log" header (WebP-Express uses the [WebP Convert](https://github.com/rosell-dk/webp-convert) for conversions).

### Notes

*Note:*
The redirect rules created in *.htaccess* are pointing to a PHP script. If you happen to change the url path of your plugins, the rules will have to be updated. The *.htaccess* also passes the path to wp-content (relative to document root) to the script, so the script knows where to find its configuration and where to store converted images. So again, if you move the wp-content folder, or perhaps moves Wordpress to a subfolder, the rules will have to be updated. As moving these things around is a rare situation, WebP Express are not using any resources monitoring this. However, it will do the check when you visit the settings page.

*Note:*
Do not simply remove the plugin without deactivating it first. Deactivation takes care of removing the rules in the *.htaccess* file. With the rules there, but converter gone, your Google Chrome visitors will not see any jpeg images.

== Limitations ==

* The plugin [should now work on Microsoft IIS server](https://github.com/rosell-dk/webp-express/pull/213), but it has not been tested thoroughly.

== Supporting WebP Express ==
Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue wasting time on this plugin:

* [Buy me a Coffee](https://ko-fi.com/rosell)
* [Buy me coffee on a regular basis](https://github.com/sponsors/rosell-dk) and help ensuring my coffee supplies doesn't run dry.

== Supporters of WebP Express ==

**Persons currently backing the project via GitHub Sponsors or patreon - Thanks!**

* Max Kreminsky
* [Mathieu Gollain-Dupont](https://www.linkedin.com/in/mathieu-gollain-dupont-9938a4a/)
* Ruben Solvang

**Persons who contributed with coffee within the last 30 days (updated biweekly) - Thanks! **

* Katja
* Devashish Datt Mamgain
* RobMoore

**Persons who contributed with extra generously amounts of coffee / lifetime backing (>30$) - thanks!:**

* Justin - BigScoots ($105)
* Sebastian ($99)
* Tammy Lee ($90)
* Max Kreminsky ($70)
* Steven Sullivan ($51)

== Frequently Asked Questions ==

= How do I verify that the plugin is working? =

**Verifying that the plugin works in "Varied image responses" mode**
1. Make sure at least one of the conversion methods are working. It should have a green checkmark next to it.
2. If you haven't saved yet, click "Save settings". This will put redirection rules into .htaccess files in the relevant directories (typically in uploads, themes and wp-content/webp-express/webp-images, depending on the "Scope" setting)
3. I assume that you checked at least one of the checkboxes in the .htaccess rules section - otherwise you might as well change to "CDN friendly" mode. The first
4. Click the "Live test" buttons to see that the enabled rules actually are working. If they are not, it *could* be that the server needs a little time to recognize the changed rules.

The live tests are quite thorough and I recommend them over a manual test. However, it doesn't hurt to do a manual inspection too.

*Doing a manual inspection*

Note that when WebP Express is serving varied image responses, the image URLs *still points to the jpg/png*. If the URL is visited using a browser that supports webp, however, the response will be a webp image. So there is a mismatch between the file extension (the filename ends with "jpg" or "png") and the file type. But luckily, the browser does not rely on the extension to determine the file type, it only looks at the Content-Type response header.

To verify that the plugin is working (without clicking the test button), do the following:

- Open the page in a browser that supports webp, ie Google Chrome
- Right-click the page and choose "Inspect"
- Click the "Network" tab
- Reload the page
- Find a jpeg or png image in the list. In the "type" column, it should say "webp"

You can also look at the headers. When WebP Express has redirected to an existing webp, there will be a "X-WebP-Express" header with the following value: "Redirected directly to existing webp". If there isn't (and you have checked "Enable redirection to converter"), you should see a "WebP-Convert-Log" header (WebP-Express uses the [WebP Convert](https://github.com/rosell-dk/webp-convert) for conversions).

= No conversions methods are working out of the box =
Don't fret - you have options!

- If you a controlling another WordPress site (where the local conversion methods DO work), you can set up WebP Express there, and then connect to it by configuring the “Remote WebP Express” conversion method.
- You can also setup the ewww conversion method. To use it, you need to purchase an api key. They do not charge credits for webp conversions, so all you ever have to pay is the one dollar start-up fee 🙂 (unless they change their pricing – I have no control over that). You can buy an api key here: https://ewww.io/plans/
- I have written a [template letter](https://github.com/rosell-dk/webp-convert/wiki/A-template-letter-for-shared-hosts) which you can send to your webhost
- You can try to get one of the local converters working. Check out [this page](https://github.com/rosell-dk/webp-convert/wiki/Meeting-the-requirements-of-the-converters) on the webp-convert wiki. There is also this [test/troubleshooting script](https://github.com/rosell-dk/webp-convert/wiki/A-PHP-script-for-the-webhost) which is handy when messing around with this.
- Finally, if you have access to another server and are comfortable with installing projects with composer, you can install [webp-convert-cloud-service](https://github.com/rosell-dk/webp-convert-cloud-service). It's open source.

Of course, there is also the option of using another plugin altogether. I can recommend Optimole. If you want to try that out and want to support me in the process, [follow this link](https://optimole.pxf.io/20b0M). It is an affiliate link and will give me a reward in case you decide to sign up.

= It doesn't work - Although test conversions work, it still serves jpeg images =
Actually, you might be mistaking, so first, make sure that you didn't make the very common mistake of thinking that something with the URL *example.com/image.jpg* must be a jpeg image. The plugin serves webp images on same URL as the original (unconverted) images, so do not let appearances fool you! Confused? See next FAQ item.

Assuming that you have inspected the *content type* header, and it doesn't show "image/webp", please make sure that:
1) You tested with a browser that supports webp (such as Chrome)
2) The image URL you are looking at are not pointing to another server (such as gravatar.com)

Assuming that all above is in place, please look at the response headers to see if there is a *X-WebP-Convert-Status* header. If there isn't, well, then it seems that the problem is that the image request isn't handed over to WebP Express. Reasons for that can be:

- You are on NGINX (or an Apache/Nginx combination). NGINX requires special attention, please look at that FAQ item
- You are on WAMP. Please look at that FAQ item

I shall write more on this FAQ item... Stay tuned.


= How can a webp image be served on an URL ending with "jpg"? =
Easy enough. Browsers looks at the *content type* header rather than the URL to determine what it is that it gets. So, although it can be confusing that the resource at *example.com/image.jpg* is a webp image, rest assured that the browsers are not confused. To determine if the plugin is working, you must therefore examine the *content type* response header rather than the URL. See the "How do I verify that the plugin is working?" Faq item.

I am btw considering making an option to have the plugin redirect to the webp instead of serving immediately. That would remove the apparent mismatch between file extension and content type header. However, the cost of doing that will be an extra request for each image, which means extra time and worse performance. I believe you'd be ill advised to use that option, so I guess I will not implement it. But perhaps you have good reasons to use it? If you do, please let me know!

= Blank images in Safari? =
WebP Express has three ways of distributing webp to webp-enabled browsers while still sending the originals to webp-disabled browsers. While method 1 can be combined with any of the other methods, you would usually just pick method 1 or one of the others if method 1 cannot be used for you.

Can some of these go wrong?
Yes. All!

**Method 1: Varied image responses**
The "Varied image responses" method adds rules to the `.htaccess` which redirects jpegs and pngs to the corresponding webps (if they exist). The rules have a condition that makes sure they only trigger for browsers supports webp images (this is established by examining the "accept" header).

I the method "varied image responses" because the response on a given image URL *varies* (the webp is served on the same URL as the jpeg/png).

In the cases where method 1 fails, it is due to systems that cache images by the URL alone. To prevent this from happening, the `.htaccess` rules adds a `Vary:Accept` response header. However, most CDNs does not respect that header unless they are configured to do so. Fortunately proxy servers respects it nicely (however often by throwing out the cached image if the accept header doesn't match)

Method 1 can go wrong if:

1. You are using a CDN and it hasn't been set up to handle varied image responses. If this has happened, it is critical that you purge the CDN cache! For information regarding CDN setups, check out the CDN section in this FAQ
2. Your server doesn't support adding response headers in `.htaccess`. On Apache, the "mod_headers" module needs to be enabled. Otherwise the all important `Vary:Accept` response header will not be set on the response.
3. Your server doesn't support SetEnv. However, that module is fortunately very common. I have posted a possible solution to make the rules work without SetEnv [here](https://wordpress.org/support/topic/setenv/).
4. You are on Nginx and you haven't created rules that adds the `Vary:Accept` header.

I do not believe it can go wrong in other ways. To be certain, please check out [this test page](http://toste.dk/rh.php). When visiting the test-page with Safari, you should see two images with the “JPG” label over them. When visiting the test-page with a browser that supports webp, you should see two images with the “WEBP” label over them. If you do not see one of these things, please report! (no-one has yet experienced that)

Since WebP Express 0.15.0 you can use the "Live test" button to check that browsers not supporting webp gets the original files and that the Vary:Accept header is returned. Note however that it may not detect CDN caching problems if the CDN doesn't cache a new image immediately - and across all its nodes.

**Method 2: Altering HTML to use picture tags**
IMG tags are replaced with PICTURE tags which has two sources. One of them points to the webp and has the "content-type" set to "image/webp". The other points to the original. The browser will select the webp source if it supports webp and the other source if it doesn't.

Method 2 can go wrong on old browser that doesn't support the picture tag syntax. However, simply enable the "Dynamically load picturefill.js on older browsers" option, and it will take care of that issue.

**Method 3: Altering HTML to point directly to webps in webp enabled browsers**
In this solution, the URLs in the HTML are modified for browsers that supports webp. Again, this is determined by examining the "accept" header. So, actually the complete page HTML varies with this method.

Method 3 can go wrong if you are using a page caching plugin if that plugin does not create a separate webp cache for webp-enabled browsers. The *Cache Enabler* plugin handles this. I don't believe there are other page caching plugins that does. There is a FAQ section in this FAQ describing how to set *Cache Enabler* up to work in tandem with WebP Express.

Note that Firefox 66+ unfortunately stopped including "image/webp" in the "accept" header it sends when requesting *the page*. While Firefox 66+ fortunately still includes "image/webp" in its accept header *for images*. That will however not get it webp images when using method 3.

= I am on NGINX or OpenResty =

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](https://github.com/rosell-dk/webp-express/issues/8)

**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"*

__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 "}".

`
&#35; WebP Express rules
&#35; --------------------
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
    ;
}

&#35; 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
      ;
}
&#35; ------------------- (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](https://wordpress.org/support/topic/nginx-server-404-not-found-when-convert-test-images/page/2/#post-11952444)

- 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](http://www.lazutkin.com/blog/2014/02/23/serve-files-with-nginx-conditionally/).

**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 "}".

`
&#35; WebP Express rules
&#35; --------------------
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 break;
}
&#35; ------------------- (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](https://wordpress.org/support/topic/nginx-server-404-not-found-when-convert-test-images/page/2/#post-11952444)

- 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](https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/). But it seems that in our case, it works. If you wish to do that, use the following rules instead:

`
&#35; WebP Express rules
&#35; --------------------
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 last;
    }
}

location ~* ^/wp-content/.*\.webp$ {
    expires 365d;
    if ($whattodo = AB) {
        add_header Vary Accept;
    }
}
&#35; ------------------- (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:

`
&#35; WebP Express rules
&#35; --------------------
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 break;
}
&#35; ------------------- (WebP Express rules ends here)
`

Discussion on this topic [here](https://wordpress.org/support/topic/nginx-rewrite-rules-4/)
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

= I am on a Windows server =
Good news! It should work now, thanks to a guy that calls himself lwxbr. At least on XAMPP 7.3.1, Windows 10. https://github.com/rosell-dk/webp-express/pull/213.

= I am on a Litespeed server =
You do not have to do anything special for it to work on a Litespeed server. You should be able to use WebP Express in any operation mode. For best performance, I however recommend that use the *LiteSpeed Cache* plugin for page caching.

LiteSpeed Cache can be set up to maintain separate page caches for browsers that supports webp and browsers that don't. Through this functionality it is possible to use "Alter HTML" with the option "Replace image URLs" and "Only do the replacements in webp enabled browsers" mode.

The setup was kindly shared and explained in detail by [@ribeiroeder](https://github.com/ribeiroeder) [here](https://github.com/rosell-dk/webp-express/issues/433)

= I am using Jetpack =
If you install Jetpack and enable the "Speed up image load times" then Jetpack will alter the HTML such that images are pointed to their CDN.

Ie:
`<img src="https://example.com/wp-content/uploads/2018/09/architecture.jpg">`

becomes:
`<img src="https://i0.wp.com/example.com/wp-content/uploads/2018/09/architecture.jpg">`

Jetpack automatically serves webp files to browsers that supports it using same mechanism as the standard WebP Express configuration: If the "Accept" header contains "image/webp", a webp is served (keeping original file extension, but setting the "content-type" header to "image/webp"), otherwise a jpg is served.

As images are no longer pointed to your original server, the .htaccess rules created by WebP Express will not have any effect.

So if you are using Jetpack you don't really need WebP Express?
Well, there is no point in having the "Speed up image load times" enabled together with WebP Express.

But there is a case for using WebP Express rather than Jetpacks "Speed up image load times" feature:

Jetpack has the same drawback as the *standard* WebP Express configuration: If a user downloads the file, there will be a mismatch between the file extension and the image type (the file is ie called "logo.jpg", but it is really a webp image). I don't think that is a big issue, but for those who do, WebP Express might still be for you, even though you have Jetpack. And that is because WebP Express can be set up just to generate webp's, without doing the internal redirection to webp (will be possible from version 0.10.0). You can then for example use the [Cache Enabler](https://wordpress.org/plugins/cache-enabler/) plugin, which is able to generate and cache two versions of each page. One for browsers that accepts webp and one for those that don't. In the HTML for webp-enabled browsers, the images points directly to the webp files.

Pro Jetpack:
- It is a free CDN which serves webp out of the box.
- It optimizes jpegs and pngs as well (but note that only about 1 out of 5 users gets these, as webp is widely supported now)

Con Jetpack:
- It is a big plugin to install if you are only after the CDN
- It requires that you create an account on Wordpress.com

Pro WebP Express:
- You have control over quality and metadata
- It is a small plugin and care has been taken to add only very little overhead
- Plays well together with Cache Enabler. By not redirecting jpg to webp, there is no need to do any special configuration on the CDN and no issue with misleading file extension, if user downloads a file.

Con WebP Express:
- If you are using a CDN and you are redirecting jpg to webp, you must configure the CDN to forward the Accept header. It is not possible on all CDNs.

= Why do I not see the option to set WebP quality to auto? =
The option will only display, if your system is able to detect jpeg qualities. To make your server capable to do that, install *Imagick extension* (PECL >= 2.2.2) or enable exec() calls and install either *Imagick* or *Gmagick*.

If you have the *Imagick*, the *Imagick binary* or the *Remote WebP Express* conversion method working, but don't have the global "auto" option, you will have the auto option available in options of the individual converter.

Note: If you experience that the general auto option doesn't show, even though the above-mentioned requirements should be in order, check out [this support-thread](https://wordpress.org/support/topic/still-no-auto-option/).

= How do I configure my CDN in "Varied image responses" operation mode? =
In *Varied image responses* operation mode, the image responses *varies* depending on whether the browser supports webp or not (which browsers signals in the *Accept* header). Some CDN's support this out of the box, others requires some configuration and others doesn't support it at all.

For a CDN to cooperate, it needs to
1) forward the *Accept* header and
2) Honour the Vary:Accept response header.

You can also make it "work" on some CDN's by bypassing cache for images. But I rather suggest that you try out the *CDN friendly* mode (see next FAQ item)

*Status of some CDN's*:

- *KeyCDN*: Does not support varied image responses. I have added a feature request [here](https://community.keycdn.com/t/support-vary-accept-header-for-conditional-webp/1864). You can give it a +1 if you like!
- *Cloudflare*: See the "I am on Cloudflare" section
- *Cloudfront*: Works, but needs to be configured to forward the accept header. Go to *Distribution settings*, find the *Behavior tab*, select the Behavior and click the Edit button. Choose *Whitelist* from *Forward Headers* and then add the "Accept" header to the whitelist.

I shall add more to the list. You are welcome to help out [here](https://wordpress.org/support/topic/which-cdns-works-in-standard-mode/).

### How do I make it work with CDN? ("CDN friendly" mode)
In *CDN friendly* mode, there is no trickery with varied image responses, so no special attention is required *on the CDN*.

However, there are other pitfalls.

The thing is that, unless you have the whole site on a CDN, you are probably using a plugin that *alters the HTML* in order to point your static assets to the CDN. If you have enabled the "Alter HTML" in WebP Express, it means that you now have *two alterations* on the image URLs!

How will that play out?

Well, if *WebP Express* gets to alter the HTML *after* the image URLs have been altered to point to a CDN, we have trouble. WebP Express does not alter external images but the URLs are now external.

However, if *WebP Express* gets to alter the HTML *before* the other plugin, things will work fine.

So it is important that *WebP Express* gets there first.

*The good news is that WebP Express does get there first on all the plugins I have tested.*

But what can you do if it doesn't?

Firstly, you have an option in WebP Express to select between:
1. Use content filtering hooks (the_content, the_excerpt, etc)
2. The complete page (using output buffering)

The content filtering hooks gets to process the content before output buffering does. So in case output buffering isn't early enough for you, choose the content filtering hooks.

There is a risk that you CDN plugin also uses content filtering hooks. I haven't encountered any though. But if there is any out there that does, chances are that they get to process the content before WebP Express, because I have set the priority of these hooks quite high (10000). The reasoning behind this is to that we want to replace images that might be inserted using the same hook (for example, a theme might use *the_content* filter to insert the featured image). If you do encounter a plugin for changing URLs for CDN which uses the content filtering hooks, you are currently out of luck. Let me know, so I can fix that (ie. by making the priority configurable)

Here are a list of some plugins for CDN and when they process the HTML:

| Plugin            | Method             | Hook(s)                                          | Priority
| ----------------- | ------------------ | ------------------------------------------------ | ---------------
| BunnyCDN          | Output buffering   | template_redirect                                | default (10)
| CDN enabler       | Output buffering   | template_redirect                                | default (10)
| Jetpack           | content filtering  | the_content, etc                                 | the_content: 10
| W3 Total Cache    | Output buffering   | no hooks. Buffering is started before hooks      |
| WP Fastest Cache  | Output buffering   | no hooks. Buffering is started before hooks      |
| WP Super Cache    | Output buffering   | init                                             | default (10)

With output buffering the plugin that starts the output buffering first gets to process the output last. So WebP Express starts as late as possible, which is on the `template_redirect` hook, with priority 10000 (higher means later). This is later than the `init` hook, which is again later than the `no hooks`.

= I am on Cloudflare =
Without configuration, Cloudflare will not maintain separate caches for jpegs and webp; all browsers will get jpeg. To make Cloudflare cache not only by URL, but also by header, you need to use the [Custom Cache Key](https://support.cloudflare.com/hc/en-us/articles/115004290387) page rule, and add *Header content*  to make separate caches depending on the *Accept* request header.

However, the *Custom Cache Key* rule currently requires an *Enterprise* account. And if you already have that, you may as well go with the *Polish* feature, which starts at the “Pro” level plan. With the *Polish* feature, you will not need WebP Express.

To make *WebP Express* work on a free Cloudflare account, you have the following choices:

1. You can configure the CDN not to cache jpeg images by adding the following page rule: If rule matches: `example.com/*.jpg`, set: *Cache level* to: *Bypass*

2. You can set up another CDN (on another provider), which you just use for handling the images. You need to configure that CDN to forward the *Accept header*. You also need to install a Wordpress plugin that points images to that CDN.

3. You can switch operation mode to "CDN friendly" and use HTML altering.

= I am on WP Engine =
From version 0.17.1 on WebP Express works with WP engine and this combination will be tested before each release.

You can use the plugin both in "Varied image responses" mode and in "CDN friendly mode".

To make the redirection work, you must:
1) Grab the nginx configuration found in the "I am on Nginx/OpenResty" section in this FAQ. Use the "try_files" variant.
2) Contact help center and ask them to insert that configuration.
3) Make sure the settings match this configuration. Follow the "beware" statements in the "I am on Nginx/OpenResty" section.

WebP Express tweaks the workings of "Redirect to converter" a bit for WP engine. That PHP script usually serves the webp directly, along with a Vary:Accept header. This header is however overwritten by the caching machinery on WP engine. As a work-around, I modified the response of the script for WP engine. Instead of serving the image, it serves a redirect to itself. As there now IS a corresponding webp, this repeated request will not be redirected to the PHP script, but directly to the webp. And headers are OK for those redirects. You can hit the "Live test" button next to "Enable redirection to converter?" to verify that this works as just described.

If you (contrary to this headline!) are in fact not on WP Engine, but might want to be, I have an affiliate link for you. It will give you 3 months free and it will give me a reward too, if you should decide to stay there. Here you go: [Get 3 months free when you sign up for WP Engine.](https://shareasale.com/r.cfm?b=1343154&u=2194916&m=41388&urllink=&afftrack=)

= WebP Express / ShortPixel setup =
Here is a recipe for using WebP Express together with ShortPixel, such that WebP Express generates the webp's, and ShortPixel only is used to create `<picture>` tags, when it detects a webp image in the same folder as an original.

**There is really no need to do this anymore, because WebP Express is now capable of replacing img tags with picture tags (check out the Alter HTML option)**

You need:
1 x WebP Express
1 x ShortPixel

*1. Setup WebP Express*
If you do not want to use serve varied images:
- Open WebP Express options
- Switch to *CDN friendly* mode.
- Set *File extension* to "Set to .webp"
- Make sure the *Convert non-existing webp-files upon request to original image* option is enabled

If you want to *ShortPixel* to create <picture> tags but still want the magic to work on other images (such as images are referenced from CSS or javascript):
- Open WebP Express options
- Switch to *Varied image responses* mode.
- Set *Destination folder* to "Mingled"
- Set *File extension* to "Set to .webp"

*2. Setup ShortPixel*
- Install [ShortPixel](https://wordpress.org/plugins/shortpixel-image-optimiser/) the usual way
- Get an API key and enter it on the options page.
- In *Advanced*, enable the following options:
    - *Also create WebP versions of the images, for free.*
    - *Deliver the WebP versions of the images in the front-end*
    - *Altering the page code, using the <PICTURE> tag syntax*
- As there is a limit to how many images you can convert freely with *ShortPixel*, you should disable the following options (also on the *Advanced* screen):
    - *Automatically optimize images added by users in front end.*
    - *Automatically optimize Media Library items after they are uploaded (recommended).*

*3. Visit a page*
As there are presumably no webps generated yet, ShortPixel will not generate `<picture>` tags on the first visit. However, the images that are referenced causes the WebP Express *Auto convert* feature to kick in and generate webp images for each image on that page.

*4. Visit the page again*
As *WebP Express* have generated webps in the same folder as the originals, *ShortPixel* detects these, and you should see `<picture>` tags which references the webp's.

*ShortPixel or Cache Enabler ?*
Cache Enabler has the advantage over ShortPixel that the HTML structure remains the same. With ShortPixel, image tags are wrapped in a `<picture>` tag structure, and by doing that, there is a risk of breaking styles.

Further, Cache Enabler *caches* the HTML. This is good for performance. However, this also locks you to using that plugin for caching. With ShortPixel, you can keep using your favourite caching plugin.

Cache Enabler will not work if you are caching HTML on a CDN, because the HTML varies depending on the *Accept* header and it doesn't signal this with a Vary:Accept header. You could however add that manually. ShortPixel does not have that issue, as the HTML is the same for all.

### WebP Express / Cache Enabler setup
The WebP Express / Cache Enabler setup is quite potent and very CDN-friendly. *Cache Enabler* is used for generating *and caching* two versions of the HTML (one for webp-enabled browsers and one for webp-disabled browsers)

The reason for doing this could be:
1. You are using a CDN which cannot be configured to work in the "Varied image responses" mode.
2. You could tweak your CDN to work in the "Varied image responses" mode, but you would have to do it by using the entire Accept header as key. Doing that would increase the risk of cache MISS, and you therefore decided that do not want to do that.
3. You think it is problematic that when a user saves an image, it has the jpg extension, even though it is a webp image.

You need:
1 x WebP Express
1 x Cache Enabler

*1. Setup WebP Express*
If you do not want to use serve varied images:
- Open WebP Express options
- Switch to *CDN friendly* mode.
- Set *File extension* to "Set to .webp"
- Enable *Alter HTML* and select *Replace image URLs*. It is not absolutely necessary, as Cache Enabler also alters HTML - but there are several reasons to do it. Firstly, *Cache Enabler* doesn't get as many URLs replaced as we do. WebP Express for example also replaces background urls in inline styles. Secondly, *Cache enabler* has [problems in edge cases](https://regexr.com/46isf). Thirdly, WebP Express can be configured to alter HTML to point to corresponding webp images, *before they even exists* which can be used in conjunction with the the *Convert non-existing webp-files upon request* option. And this is smart, because then you don't have trouble with *Cache Enabler* caching HTML which references the original images due to that some images hasn't been converted yet.
- If you enabled *Alter HTML*, also enable *Reference webps that hasn't been converted yet* and *Convert non-existing webp-files upon request*
- If you did not enable *Alter HTML*, enable *Convert non-existing webp-files upon request to original image*

If you want to *Cache Enabler* to create <picture> tags but still want the magic to work on other images (such as images are referenced from CSS or javascript):
- Open WebP Express options
- Switch to *Varied image responses* mode.
- Set *Destination folder* to "Mingled"
- Set *File extension* to "Set to .webp"
- I suggest you enable *Alter HTML* and select *Replace image URLs*. And also enable *Reference webps that hasn't been converted yet* and *Convert non-existing webp-files upon request*.

*2. Setup Cache Enabler*
- Open the options
- Enable of the *Create an additional cached version for WebP image support* option

*3. If you did not enable Alter HTML and Reference webps that hasn't been converted yet: Let rise in a warm place until doubled*
*WebP Express* creates *webp* images on need basis. It needs page visits in order to do the conversions . Bulk conversion is on the roadmap, but until then, you need to visit all pages of relevance. You can either do it manually, let your visitors do it (that is: wait a bit), or, if you are on linux, you can use `wget` to grab your website:

```
wget -e robots=off -r -np -w 2 http://www.example.com
```

**flags:**
`-e robots=off` makes wget ignore rules in robots.txt
`-np` (no-parent) makes wget stay within the boundaries (doesn't go into parent folders)
`w 2` Waits two seconds between each request, in order not to stress the server

*4. Clear the Cache Enabler cache.*
Click the "Clear Cache" button in the top right corner in order to clear the Cache Enabler cache.

*5. Inspect the HTML*
When visiting a page with images on, different HTML will be served to browsers, depending on whether they support webp or not.

In a webp-enabled browser, the HTML may look like this: `<img src="image.webp">`, while in a non-webp enabled browser, it looks like this: `<img src="image.jpg">`


*6. Optionally add Cache Enabler rewrite rules in your .htaccess*
*Cache Enabler* provides some rewrite rules that redirects to the cached file directly in the `.htaccess`, bypassing PHP entirely. Their plugin doesn't do that for you, so you will have to do it manually in order to get the best performance. The rules are in the "Advanced configuration" section on [this page](https://www.keycdn.com/support/wordpress-cache-enabler-plugin).

= Does it work with lazy loaded images? =
No plugins/frameworks has yet been discovered, which does not work with *WebP Express*.

The most common way of lazy-loading is by setting a *data-src* attribute on the image and let javascript use that value for setting the *src* attribute. That method works, as the image request, seen from the server side, is indistinguishable from any other image request. It could however be that some obscure lazy load implementation would load the image with an XHR request. In that case, the *Accept* header will not contain 'image/webp', but '*/*', and a jpeg will be served, even though the browser supports webp.

The following lazy load plugins/frameworks has been tested and works with *WebP Express*:
- [BJ Lazy Load](https://da.wordpress.org/plugins/bj-lazy-load/)
- [Owl Carousel 2](https://owlcarousel2.github.io/OwlCarousel2/)
- [Lazy Load by WP Rocket](https://wordpress.org/plugins/rocket-lazy-load/)

I have only tested the above in *Varied image responses* mode, but it should also work in *CDN friendly* mode. Both *Alter HTML* options have been designed to work with standard lazy load attributes.

= Can I make an exceptions for some images? =
There can be instances where you actually need to serve a jpeg or png. For example if you are demonstrating how a jpeg looks using some compression settings. It is possible to bypass both the redirection and the HTML altering for certain images. Here is how:

*Alter HTML*
Alter HTML is programmed not to substitute image URLs with query strings (better safe than sorry). You can exploit that and simply add ie ?original to the image URLs in question.

*Redirection*
To bypass the *redirection*, you can add the following in the `.htaccess` where *WebP Express* has placed its rules (this is usually in the `wp-content` folder). The rules needs to be added *above* the rules inserted by *WebP Express*.

`
RewriteCond %{QUERY_STRING} original
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule . - [L]
`
With those rules in place, you can add "?original" to the URLs of those images that you want to keep serving as jpg / png.

Alternatively, you can specify the filenames individually in the `.htaccess`:

`
RewriteRule ^uploads/2019/02/example-of-jpg-compressed-to-80\.jpg - [L]
RewriteRule ^uploads/2019/02/image2\.jpg - [L]
RewriteRule . - [L]
`
If you got any further questions, look at, or comment on [this topic](https://wordpress.org/support/topic/can-i-make-an-exception-for-specific-post-image/)

= Update failed and cannot reinstall =
The 0.17.0 release contained binaries with dots in their filenames, which caused the unpacking during update to fail on a few systems. This failure could leave an incomplete installation. With important files missing - such as the main plugin file - Wordpress no longer registers that the plugin is there (it is missing from the list). However, the folder is there in the file system and trying to install WebP Express again fails because Wordpress complains about just that. The solution is to remove the "webp-express" folder in "plugins" manually (via ftp or a plugin, such as File Manager) and then install WebP Express anew. The setting will be intact. The filenames that caused the trouble where fixed in 0.17.2.

=  Alter HTML only replaces some of the images =

If you are wondering why Alter HTML are missing some images, it can be due to one of the following reasons:

- WebP Express doesn't convert external images, only images on your server. Alter HTML will therefore not alter URLS that unless they point to your server or a CDN that you have added in the *CDN hostnames* section
- WebP Express has a "Scope" option, which for example can be set to "Uploads and themes". Only images that resides within the selected scope are replaced with webp.
- If you have selected `<picture>` tags syntax, only images inserted with `<img>`-tags will be replaced (CSS images will not be replaced). Additionally, the `<img>`-tag must have a "src" attribute or a commonly used data attribute for lazyloading (such as “data-src” or “data-lazy-src”)
- If you have set the "How to replace" option to "Use content filtering hooks", images inserted with some third party plugins/themes might not be replaced. To overcome that, change that setting to "The complete page".
- The image might have been inserted with javascript. WebP Express doesn't changSome plugins might insert the

= When is feature X coming? / Roadmap =
No schedule. I move forward as time allows. I currently spend a lot of time answering questions in the support forum. If someone would be nice and help out answering questions here, it would allow me to spend that time developing. Also, donations would allow me to turn down some of the more boring requests from my customers, and speed things up here.

Here are my current plans ahead: 0.18 will probably be a file manager-like interface for converting / bulk converting / viewing conversion logs / comparing original vs webp visually - kind of a merge of current "test converter" and "bulk conversion" interfaces, and with an addition of a file explorer. 0.19 might allow excluding certain files and folders. 0.20 could be supporting Save-Data header in Varied Image Responses mode (send extra compressed images to clients who wants to use as little bandwidth as possible). 0.21 might be displaying rules for NGINX. 0.21 might be an effort to allow webp for all browsers using [this javascript library](http://libwebpjs.hohenlimburg.org/v0.6.0/). Unfortunately, the javascript library does not (currently) support srcset attributes, which is why I moved this item down the priority list. We need srcset to be supported for the feature to be useful. 0.21 might be WAMP support. The current milestones, their subtasks and their progress can be viewed here: https://github.com/rosell-dk/webp-express/milestones

If you wish to affect priorities, it is certainly possible. You can try to argue your case in the forum or you can simply let the money do the talking. By donating as little as a cup of coffee on [ko-fi.com/rosell](https://ko-fi.com/rosell), you can leave a wish. I shall take these wishes into account when prioritizing between new features.

= Can I buy you a cup of coffee? =
You sure can! To do so, [go here!](https://ko-fi.com/rosell). If payment doesn't work for your country, [try here instead](https://buymeacoff.ee/rosell).

If you want to make sure that my coffee supplies don't run dry, you can even buy me a cup of coffee on a regular basis [by going here](https://github.com/sponsors/rosell-dk)


== Screenshots ==

1. WebP Express settings

== Changelog ==

= 0.18.1 =
*(released: 24 Sep 2020)*
* Bugfix: Bulk Convert failed to show list on systems that did not have the [utf8-encode()](https://www.php.net/manual/en/function.utf8-encode.php) function.

= 0.18.0 =
*(released: 24 Sep 2020)*
* You can now set cache control header in CDN friendly mode too
* The code for testing what actually works in .htaccess files on the server setup has been moved to a new library: [htaccess-capability-tester](https://github.com/rosell-dk/htaccess-capability-tester). It has been strengthened in the process.
* Improved diagnosing in the "Live test" buttons
* Simplified the logic for adding "Vary header" in the .htaccess residing in the cache dir. The logic no longer depends on the Apache module "mod_envif" being installed. mod_envif has Apache "Base" status, which means it is very rarely missing, so I decided not to trigger automatically updating of the .htaccess rules. To apply the change, you must click the button that forces .htaccess regeneration
* The plugin has a folder called "wod" which contains php scripts for converting an image to webp. This is used for the function that rely on redirect magic to trigger conversion ("Enable redirection to converter?" and "Create webp files upon request?"). The .htaccess file in the "wod" folder in the plugin dir contains directives for modifying access (in order to counterfight rules placed by security plugins for disallows scripts to be run directly). However if these directives has been disallowed in the server setup, any request to a file in the folder will result in a 500 internal server error. To circumvent this, a "wod2" folder has been added, which contains the same scripts, but without the .htaccess. Upon saving, WebP Express now automatically checks which one works, and points to that in the .htaccess rules.
* Bugfix: webp mime type was not registred in .htaccess in "CDN friendly" mode. This is a minor fix so I decided not to update the .htaccess automatically. To apply it, you must click the button that forces .htaccess regeneration.
* Bugfix: Bulk convert failed to load the list when there were filenames containing non-unicode characters
* Added a new way to support me. I'm on [GitHub Sponsors](https://github.com/sponsors/rosell-dk)!

For more info, see the closed issues on the 0.18.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/33?closed=1

= 0.17.5 =
*(released: 11 Aug 2020)*
* Fixed "Path is outside resolved document root" in a certain symlinked configuration. Thanks to @spiderPan on github for providing the fix.
* Added content filtering hooks for several third party plugins including ACF and WooCommerce Product Images. With this change, the "Use content filtering hooks" in Alter HTML works in more scenarios, which means there are fewer scenarios where you have to resort to the slower "The complete page" option. Thanks to alextuan for providing the contribution
* Fixed problems with Alter HTML when migrating: Absolute paths were cached in the database and the cache was only updated upon saving settings. The paths are not cached anymore (recalculating these on each page load is not a performance problem)

For more info, see the closed issues on the 0.17.5 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/30?closed=1

= 0.17.4 =
*(released: 26 Jun 2020)*
* Fixed bug: Configuration was repeatedly resetting for some users
* Fixed "Path is outside resolved document root" on file conversion attempts in Windows. Thanks to @Ruzgfpegk from Japan for providing the fix.
* Fix errors not caught in the selftest. Thanks to Benji Bilheimer from Germany providing the fix.
* Fix errors not caught in the selftest with unverified certificates. Thanks to Rikesh Ramlochund from Mauritius for providing the fix.
* Fixed errors with filenames containing encoded symbols. Thanks to Eddie Zhou from Canada for the fix.

For more info, see the closed issues on the 0.17.3 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/32?closed=1

= 0.17.3 =
*(released: 3 Feb 2020)*

* Fixed critical bug: Fatal error after updating plugin (if one had been postponing updating WebP Express for a while and then updated Wordpress to 5.2 and THEN updated WebP Express)
* A critical bug was fixed in the webp-convert library (PHP 7.4 related)
* A critical bug was fixed in dom-util-for-webp library (PHP 7.4 related)
* Alter HTML now processes the "poster" attribute in Video tags. Thanks to @MikhailRoot from Russia for the PR on github.
* On some Litespeed hosts, WebP Express reported that mod_headers was not available even though it was. Thanks to @lubieowoce from Poland for the PR on github)

For more info, see the closed issues on the 0.17.3 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/31?closed=1

= 0.17.2 =
*(released: 5 Oct 2019)*

* Fixed bug: Updating plugin failed on a few hosts (in the unzip phase). Problem was introduced in 0.17.0 with the updated binaries.
* Fixed bug: Alter HTML used the protocol (http/https) for the site for generated links (rather than keeping the protocol for the link). Thanks to Jacob Gullberg from Sweden for discovering this bug.

If you experienced update problems due to the update bug, you will probably be left with an incomplete installation. Some of the plugin files are there, but not all. Especially, the main plugin file (webp-express.php) is missing, which means that Wordpress don't "see" the plugin (it is missing from the list). Trying to install WebP Express again will probably not work, because the "webp-express" folder is already there. You will then have to remove the "webp-express" folder in "plugins" manually (via ftp or a plugin, such as File Manager).

For more info, see the closed issues on the 0.17.2 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/29?closed=1

= 0.17.1 =
*(released: 3 Oct 2019)*

* Fixed NGINX rules in FAQ (added xdestination for the create webp upon request functionality)
* Fixed issue with Alter HTML. Thanks to @jonathanernst for discovering issue and supplying the patch.
* WebP Express now works on WP Engine. Check out the new "I am on WP Engine" section in the FAQ
* Miscellaneous bug fixes

For more info, see the closed issues on the 0.17.1 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/27?closed=1

= 0.17.0 =
*(released: 27 sep 2019)*

* Cwebp conversion method runs on more systems (not subject to open_basedir restrictions and also tries "pure" cwebp command). Thanks to cng11 for reaching out so I spotted this.
* Ewww conversion method no longer does a remote api-key check for each conversion - so it is faster. If an ewww conversions fails due to a non-functional key, the key will not be tried again (until next time the options are saved)
* Updated cwebp binaries to version 1.0.3

= 0.16.0 =
*(released: 24 sep 2019)*

* Added option to specify CDN urls in Alter HTML. Thanks to Gunnar Peipman from Estonia for suggesting this.
* Direct Nginx users to Nginx FAQ section on welcome page
* Fixed Bulk Conversion halting due to nonce expiry
* Fixed unexpected output upon reactivation
* Added affiliate link to [Optimole](https://optimole.pxf.io/20b0M) in the "Don't despair - You have options!" message

= 0.15.3 =
*(released: 19 sep 2019)*

* Fixed fatal error upon activation for systems which cannot use document root for structuring (rare)

= 0.15.2 =
*(released: 17 sep 2019)*

* Fixed the bug when File extension was set to "Set to .webp". It was buggy when file extension contained uppercase letters.

= 0.15.1 =
*(released: 17 sep 2019)*

* Bug alert: Added alert about a bug when destination folder is set to "mingled" and File extension is set to "Set to .webp"
* Bugfix: Plugin URL pointed to webpexpress - it should point to parent. This gave trouble with images located in plugins. Thanks to Guillaume Meyer from Switzerland for discovering and reporting.
* Bugfix: Images with uppercase chars in extension did not get Vary:Accept
* Bugfix: There were issues with "All content" and destination:document-root when webp-realizer is activated

For more info, see the closed issues on the 0.15.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/23?closed=1

= 0.15.0 =
*(released: 17 sep 2019)*

* Provided test-buttons for checking if the redirects works.
* You can now choose which folders WebP Express is active in. Ie "Uploads and Themes".
* You can now choose an alternative file structure for the webps which does not rely on DOCUMENT_ROOT being available.
* WebP Express can now handle when wp-content is symlinked.
* The .htaccess rules are now divided across folders. Some rules are needed where the source files are located, some where the webp files are located.
* Added option to convert only PNG files
* And a couple of bugfixes.

For more info, see the closed issues on the 0.15.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/22?closed=1

= 0.14.22 =
*(released: 4 aug 2019)*

* Fixed bug in Nginx rules in the FAQ (they did not take into account that the webp images outside upload folder are never stored "mingled")
* Fixed bug: The extension setting was not respected - it was always appending ".webp", never setting. Thanks to Florian from Germany and Derrick Hammer from USA for reporting.
* Fixed bug: It turns out that Imagick gives up quality detection for some images and returns 0. This resulted in very poor quality webps when the quality was set to same as jpeg. The 0 is now treated as a failure and the max-quality will be used for such images. Thanks to @sanjayojha303 from India for reporting that there were quality problems on some images.
* Fixed bug-like behavior: The conversion scripts no longer requires that the respective setting is on for Nginx. Thanks to Mike from Russia for reporting this.
* Fixed bug: The error handler in webp-convert for handling warnings could in some cases result in endless recursion. For some the result was that they could no longer upload images. Thanks to Tobias Keller from Germany for reporting this bug.
* Fixed minor bug: Attempt to call private method in a rare scenario (when accessing one of the php scripts in the "wod" folder directly - which is not allowed). Thanks to Giacomo Lawrance from the U.K. for providing input that led to this discovery.
* Fixed minor bug: It was not tested whether a corresponding webp existed before trying to deleting it when an image was deleted. This produced warnings in debug.log.
* Security related: Added sanitizing of paths to avoid false positives on coderisk.com (there where no risk because already test the paths for sanity - but this is not detected by coderisk, as the variable is not modified). This was simply done in order get rid of the warnings at coderisk.
* Security fix: Paths were not sanitized on Windows.

= 0.14.21 =
*(released: 30 jun 2019)*

* Hopefully fixed WebP Express Error: "png" option is Object

= 0.14.20 =
*(released: 29 jun 2019)*

* Fixed bug: Ewww api-key was forgot upon saving options

= 0.14.19 =
*(released: 28 jun 2019)** Provided test-buttons for checking if the redirects works.
* You can now choose which folders WebP Express is active in. Ie "Uploads and Themes".
* You can now choose an alternative file structure for the webps which does not rely on DOCUMENT_ROOT being available.
* WebP Express can now handle when wp-content is symlinked.
* The .htaccess rules are now divided across folders. Some rules are needed where the source files are located, some where the webp files are located.
* And a couple of bugfixes.

For more info, see the closed issues on the 0.15.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/22?closed=1

* Removed a line that might course Sanity Check to fail ("path not within document root")

= 0.14.18 =
*(released: 28 jun 2019)*

* Fixed Sanity Error: Path is outside allowed path on systems using symlinked folders
* Updated cache breaking token for javascript in order for the last fix for changing password with Remote WebP Express to take effect
* Fixed undefined variable error in image_make_intermediate_size hook, which prevented webps thumbnails to be generated upon upload
* Minor bug fix in cwebp converter (updated to webp-convert v.2.1.4)

= 0.14.17 =
*(released: 28 jun 2019)*

* Relaxed abspath sanity check on Windows
* Fixed updating password for Remote WebP Express

= 0.14.16 =
*(released: 26 jun 2019)*

* Fixed conversion errors using Bulk convert or Test convert on systems with symlinked folders

= 0.14.15 =
*(released: 26 jun 2019)*

* Fixed errors with "redirect to conversion script" on systems with symlinked folders
* Fixed errors with "redirect to conversion script" on systems where the filename cannot be passed through an environment variable

= 0.14.14 =
*(released: 26 jun 2019)*

* Fixed errors on systems with symlinked folders

= 0.14.13 =
*(released: 26 jun 2019)*

* Fixed errors in conversion scripts

= 0.14.12 =
*(released: 26 jun 2019)*

* Fixed critical bug

= 0.14.11 =
*(released: 24 jun 2019)*

The following security fixes has been applied in 0.14.0 - 0.14.11:
It is urged that you upgrade all of you WebP Express installations!

– Security fix: Closed a security hole that could be used to view the content of any file on the server (provided that the full path is known or guessed). This is a very serious flaw, which unfortunately has been around for quite a while.
– Security fix: Added capability checks to options page.
– Security fix: Sanitized user input.
– Security fix: Added checks for file paths and directories.
– Security fix: Nonces and capability checks for AJAX calls.

= 0.14.10 =
*(released: 24 jun 2019)*

* Security related

= 0.14.9 =
*(released: 22 jun 2019)*

* Security related

= 0.14.8 =
*(released: 21 jun 2019)*

* Security related

= 0.14.7 =
*(released: 20 jun 2019)*

* Security related: Removed unneccesary files from webp-convert library

= 0.14.6 =
*(released: 20 jun 2019)*

* Security related

= 0.14.5 =
*(released: 20 jun 2019)*

* Security related

= 0.14.4 =
*(released: 18 jun 2019)*

* Now bundles with multiple cwebp binaries for linux for systems where 1.0.2 fails.

= 0.14.3 =
*(released: 18 jun 2019)*

* Fixed filename of supplied cwebp for linux (bug was introduced in 0.14.2)

= 0.14.2 =
*(released: 17 jun 2019)*

* Fixed problem with older versions of cwebp
* Fixed that images was not deleted
* Fixed cache problem on options page on systems that disables cache busting (it resulted in "SyntaxError: JSON.parse")

= 0.14.1 =
*(released: 15 jun 2019)*

* Security related

= 0.14.0 =
*(released: 15 jun 2019)*

* Security fix: Closed a security hole that could be used to view the content of any file on the server (provided that the full path is known or guessed). This is a very serious flaw, which has been around for quite a while. I urge you to upgrade to 0.14.0.
* Added new "encoding" option, which can be set to auto. This can in some cases dramatically reduce the size of the webp. It is supported by all converters except ewww and gd.
* Added new "near-lossless" option (only for cwebp and vips). Using this is a good idea for reducing size of lossless webps with an acceptable loss of quality
* Added new "alpha-quality" option (all converters, except ewww and gd). Using this is a good idea when images with transparency are converted to lossy webp - it has the potential to reduce the size up to 50% (depending on the source material) while keeping an acceptable level of quality
* Added new conversion methods: Vips and GraphicsMagick
* Imagick conversion method now supports webp options (finally cracked it!)
* Using MimeType detection instead of relying on file extensions
* In "test" converter you now change options and also test PNG files
* Added conversion logs
* PNGs are now enabled by default (with the new conversion features especially PNGs are compressed much better)

For more info, see the closed issues on the 0.14.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/9?closed=1

= 0.13.2 =
*(released: 16 may 2019)*

* Fixed Fatal error on image upload in combination with the [Enable Media Replace](https://de.wordpress.org/plugins/enable-media-replace/) plugin. Thanks to Alexander Graef from Germany for reporting.
* It seems we finally nailed the blank settings page bug. Thanks to all involved, especially Richard Spenceley from the UK

= 0.13.1 =
*(released: 10 may 2019)*

* Fixed critical bug which could result in update failures in the Gutenberg editor. Thanks to Andrei Glingeanu from Moldova for his part in solving this.
* Fixed bug that caused the Bulk convert to start over. Thanks to Bas van Dijk, presumably from the Netherlands, for finding the root cause.
* On Nginx (in some configurations), the script that triggered conversion were exiting prematurely. Thanks to Sam Benson from the UK for fixing this.
* Improved Bulk conversion client, which was slowing down when many images where converted.
* A class had existential problems on HHVM. Thanks to @jaumerrr for posting the PHP error message.
* When selecting "custom" in the Cache-Control dropdown, the default text was invalid syntax. Thanks to Kevin Batdorf from Thailand for discovering this.
* When an image was deleted, the corresponding webp image was not automatically deleted. Thanks to Tobias Keller from Germany for pointing out that this could potentially lead to old webp images being shown.

For more info, see the closed issues on the 0.13.1 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/17?closed=1

= 0.13.0 =
*(released: 21 mar 2019)*

* Bulk Conversion
* Fixed problems with Gd converter and PNG
* Optinally auto convert upon media upload
* Windows fix (thanks, lwxbr!)

For more info, see the closed issues on the 0.13.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/16?closed=1

= 0.12.2 =
*(released 8 mar 2019)*

* Fixed bug: On some nginx configurations, the newly added protection against directly calling the converter scripts were triggering also when it should not.

= 0.12.1 =
*(released 7 mar 2019)*

* Fixed bug: Alter HTML crashed when HTML was larger than 600kb and "image urls" where selected

= 0.12.0 =
*(released 5 mar 2019)*

* Multisite support (!)
* A new operation mode: "No conversion", if you do not want to use WebP Express for converting. Replaces the old "Just redirect" mode
* Added capability testing of .htaccess. The .htaccess rules are now tailored to the capabilities on the system. For example, on some platforms the filename of a requested image is passed to the converter script through the query string, but on platforms that supports passing it through an environment variable, that method is used instead
* Picturefill.js is now optional (alter html, picture tag)
* A great bunch more!

For more info, see the closed issues on the 0.12.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/12?closed=1

= 0.11.3 =
*(released 18 feb 2019)*

* Fixed bug: Alter HTML caused media library not to display images on some systems. Alter HTML is now disabled in admin mode.
* Alter HTML (picture tags) could produce the source tags with "src" attribute. But source tags inside picture tags must use "srcset" attribute. Fixed.
* Alter HTML (image urls): srcsets containing "x" descriptors wasn't handled (ie, srcset="image.jpg 1x")
* Fixed rewrite rules when placed in root so they are confined to wp-content and uploads. In particular, they no longer apply in wp-admin area, which might have caused problems, ie with media library.
* Added warning when rules are placed in root and "Convert non-existing webp-files upon request" feature is enabled and WebP Express rules are to be placed below Wordpress rules
* Fixed bug: The code that determined if WebP Express had placed rules in a .htaccess failed in "CDN friendly" mode. The effect was that these rules was not cleaned up upon plugin deactivation

= 0.11.2 =
*(released 14 feb 2019)*

* Fixed bug which caused Alter HTML to fail miserably on some setups
* AlterHTML now also looks for lazy load attributes in DIV and LI tags.

= 0.11.1 =
*(released 6 feb 2019)*

* Fixed bug which caused the new "Convert non-existing webp-files upon request" not to work on all setups

= 0.11.0 =
*(released 6 feb 2019)*
* Alter HTML to point to webp files (choose between picture tags or simply altering all image urls)
* Convert non-existing webp-files upon request (means you can reference the converted webp files before they are actually converted!)

For more info, see the closed issues on the 0.11.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/14?closed=1

= 0.10.0 =
*(released 7 jan 2019)*

* Introduced "Operation modes" in order to keep setting screens simple but still allow tweaking
* WebP Express can now be used in conjunction with Cache Enabler and ShortPixel
* Cache-Control header is now added in *.htaccess*, when redirecting directly to existing webp

For more info, see the closed issues on the 0.10.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/7?closed=1

= 0.9.1 =
*(released 28 dec 2018)*

* Fixed critical bug causing blank page on options page

= 0.9.0 =
*(released 27 dec 2018)*
* Optionally make .htaccess redirect directly to existing webp (improves performance)
* Optionally do not send filename from *.htaccess* to the PHP in Querystring, but use other means (improves security and reduces risks of problems due to firewall rules)
* Fixed some bugs

For more info, see the closed issues on the 0.9.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.9.0

= 0.8.1 =
*(released 11 dec 2018)*

* Fixed javascript bug

= 0.8.0 =
*(released 11 dec 2018)*

* New conversion method, which calls imagick binary directly. This will make WebP express work out of the box on more systems
* Made sure not to trigger LFI warning i Wordfence (to activate, click the force .htaccess button)
* Imagick can now be configured to set quality to auto on systems where the auto option isn't generally available
* Added Last-Modified header to images. This makes image caching work better
* On some systems, converted files where stored in ie *..doc-rootwp-content..* rather than *..doc-root/wp-content..*. This is fixed, a clean-up script corrects the file structure upon upgrade.
* Added condition in .htaccess that checks that source file exists before handing over to converter

For more info, see the closed issues on the 0.8.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0

= 0.7.2 =
*(released 21 nov 2018)*
Fixed a critical bug which generated an error message which caused corrupt images. It was not the bug itself, but the error message it generated, that caused the images to be corrupted. It only happened when debugging was enabled in php.ini

= 0.7.1 =
*(released 9 nov 2018)*
Fixed minor "bug". The Api version combobox in Remote WebP Express converter was showing on new sites, but I only want it to show when old api is being used.

= 0.7.0 =
*(released 9 nov 2018)*
This version added option to provide conversion service to other sites!

For more info, see the closed issues on the 0.7.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.7.0

= 0.6.0 =
*(released 4 okt 2018)*
This version added option for setting caching header, fixed a serious issue with *Imagick*, added a new converter, *Gmagick*, added a great deal of options to *Cwebp* and generally improved the interface.

* Added option for caching
* Fixed long standing and serious issue with Imagick converter. It no longer generates webp images in poor quality
* Added gmagick as a new conversion method
* WebPExpress now runs on newly released WebP-Convert 1.2.0
* Added many new options for *cwebp*
* You can now quickly see converter status by hovering over a converter
* You can now choose between having quality auto-detected or not (if the server supports detecting quality).
* If the server does not support detecting quality, the WPC converter will display a quality "auto" option
* Added special intro message for those who has no working conversion methods
* Added help texts for options
* Settings are now saved, when changing converter options. Too many times, I found myself forgetting to save...

For more info, see the closed issues on the 0.6.0 milestone on our github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.6.0

= 0.5.0 =
*(released 14 sep 2018)*
This version works on many more setups than the previous. Also uses less resources and handles when images are changed.

* Configuration is now stored in a separate configuration file instead of storing directly in the *.htaccess* file and passing it on via query string. When updating, these settings are migrated automatically.
* Handles setups where Wordpress has been given its own directory (both methods mentioned [here](https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory))
* Handles setups where *wp-content* has been moved, even out of Wordpress root.
* Handles setups where Uploads folder has been moved, even out of *wp-content*.
* Handles setups where Plugins folder has been moved, even out of *wp-content* or out of Wordpress root
* Is not as likely to be subject to firewalls blocking requests (in 0.4.0, we passed all options in a querystring, and that could trigger firewalls under some circumstances)
* Is not as likely to be subject to rewrite rules from other plugins interfering. WebP Express now stores the .htaccess in the wp-content folder (if you allow it). As this is deeper than the root folder, the rules in here takes precedence over rules in the main *.htaccess*
* The *.htaccess* now passes the complete absulute path to the source file instead of a relative path. This is a less error-prone method.
* Reconverts the webp, if source image has changed
* Now runs on version 1.0.0 of [WebP On Demand](https://github.com/rosell-dk/webp-on-demand). Previously ran on 0.3.0
* Now takes care of only loading the PHP classes when needed in order not to slow down your Wordpress. The frontend will only need to process four lines of code. The backend footprint is also quite small now (80 lines of code of hooks)
* Now works in Wordpress 4.0 - 4.6.
* Added cache-breaking tokens to image test links
* Denies deactivation if rewrite rules could not be removed
* Refactored thoroughly
* More helpful texts.
* Extensive testing. Tested on Wordpress 4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8 and 4.9. Tested with PHP 5.6, PHP 7.0 and PHP 7.1. Tested on Apache and LiteSpeed. Tested when missing various write permissions. Tested migration. Tested when installed in root, in subfolder, when Wordpress has its own directory (both methods), when wp-content is moved out of Wordpress directory, when plugins is moved out of Wordpress directory, when both of them are moved and when uploads have been moved.

For more info, see the closed issues on the 0.5.0 milestone on our github repository: https://github.com/rosell-dk/webp-express/milestone/2?closed=1

For older releases, check out changelog.txt

== Upgrade Notice ==

= 0.18.2 =
* Fixed bug on settings page

= 0.18.1 =
* Minor bug fix for bulk convert

= 0.18.0 =
* General maintenance and improvements

= 0.17.5 =
* Various fixes, mainly by community.

= 0.17.4 =
* Various fixes by community. Maintainer is partly back. Will be fully back mid august.

= 0.17.3 =
* Fixed two critical bugs. One occurred on PHP 7.4, the other when updating old WebP Express on Wordpress 5.3

= 0.17.2 =
* Fixed bug: Updating plugin failed on a few hosts (in the unzip phase). The problem was introduced in 0.17.0 where the binaries contains dots in their filename.

= 0.17.1 =
* Miscellaneous bug fixes. Including the NGINX rules in the FAQ (added "xdestination" argument to webp-realizer.php). Now works with WP Engine.

= 0.17.0 =
* Improved Cwebp availability and Ewww performance. And updated cwebp binaries to version 1.0.3

= 0.16.0 =
* Various improvements and fixes

= 0.15.3 =
* Fixed fatal error upon activation for systems which cannot use document root for structuring (rare)

= 0.15.2 =
* Fixed the bug when File extension was set to "Set to .webp". It was buggy when file extension contained uppercase letters.

= 0.15.1 =
* Multiple bug fixes

= 0.15.0 =
* New "Scope" and "destination structure" options, nice test buttons and a lot of work behind the surface

= 0.14.22 =
* A bundle of bug fixes and a security fix for Windows

= 0.14.21 =
* Hopefully fixed WebP Express Error: "png" option is Object

= 0.14.20 =
* Ewww api-key was forgotten upon saving options

= 0.14.19 =
* Bug fix

= 0.14.18 =
* Multiple bug fixes

= 0.14.17 =
* Relaxed abspath sanity check on Windows and fixed updating password for Remote WebP Express

= 0.14.16 =
* Fixed more errors on systems with symlinked folders

= 0.14.15 =
* Fixed errors with "redirect to conversion script"

= 0.14.14 =
Fixed errors on systems with symlinked folders

= 0.14.13 =
Fixed errors in conversion scripts

= 0.14.12 =
Fixed critical bug

= 0.14.11 =
Important security fixes. Upgrade immediately!

= 0.14.10 =
Security related

= 0.14.9 =
Security related

= 0.14.8 =
Security related

= 0.14.7 =
Security related: Removed unneccesary files from webp-convert library

= 0.14.6 =
Security related

= 0.14.5 =
Security related

= 0.14.4 =
Now bundles with multiple cwebp binaries for linux for systems where 1.0.2 fails.

= 0.14.3 =
Fixed supplied binary for cwebp (linux)

= 0.14.2 =
A couple of bugfixes

= 0.14.1 =
Security related

= 0.14.0 =
New awesome conversion options that gets you even smaller webp files without compromising quality.

= 0.13.2 =
Fixed critical error on upload (can occur in combination with some plugins), and it seems we finally nailed the blank settings page bug.

= 0.13.1 =
Fixed several bugs. You should update...

= 0.13.0 =
Bulk Conversion, fixed problem with Gd converter and PNGs and more...

= 0.12.2 =
Fixed bug: On some nginx configurations, the newly added protection against directly calling the converter scripts were triggering also when it should not.

= 0.12.1 =
Fixed bug: Alter HTML crashed when HTML was larger than 600kb and "image urls" where selected

= 0.12.0 =
Multisite support and a new operation mode

= 0.11.3 =
Fixed several bugs. You should update :)

= 0.11.0 =
WebP Express can now alter HTML to either point to webp images directly or by using the picture tag syntax. Also, non-existing webp-files can be converted upon request (means you can reference the converted webp files before they are actually converted!)

= 0.10.0 =
WebP Express can now be used in conjunction with Cache Enabler and ShortPixel. Also introduced "Operation modes" in order to keep setting screens simple but still allow tweaking.

= 0.9.1 =
Fixed critical bug causing options page to go blank

= 0.9.0 =
Option to redirect to existing webp images directly in .htaccess (improves performance)

= 0.8.0 =
New converter and miscellaneous improvements
