WebP Express


Almost 4 out of 5 mobile 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 plugin basically routes jpeg/png images to an image converter, or – if the image converter has already converted the image – directly to a converted image. The approach has the benefit that is works regardless of how an image found its way into your server – be it Media Library, Galleries, or even theme images referenced with CSS.

The plugin is developed on github. It builds upon the WebPConvert library and the “WebP On Demand” solution described here


  • 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 difference when abroad and in the parts of the world with slow and expensive internet connections.
  • Currently ~73% of all traffic, and ~78% of mobile browsing traffic are done with browsers supporting webp. With Mozilla and Microsoft finally on board, these numbers are bound to increase. Check current numbers on caniuse.com).


  • The plugin does not work on Microsoft IIS server, nor in WAMP
  • The plugin has not been tested with multisite installation (it is on the roadmap!).

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:


  • WebP Express settings


  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


You configure the plugin in Settings > WebP Express.

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 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 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 on how to do that

The auto quality

If your server has imagick og gmagick installed, the plugin will be able to detect the quality of a jpeg, and use the same quality for the converted webp. You can tell if it does, by looking at the quality option. If it allows you to select “auto” quality, it is available, otherwise it is not, and you will only have the option to set a specific quality for all conversions. Auto should be chosen, if available, as this ensures that each conversion are converted with an appropriate quality. Say you have a jpeg with low quality (say 30). The best result, is achieved by converting it to the same quality. Converting it with high quality (say 80), will not get you better quality, only a larger file.

If you do not the “auto” option available:
– Install imagick or gmagick, if you can
– Use “Remote WebP Express” converter to connect to a site, that does have the auto option available
– 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%.


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 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.

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.

The plugin has not been tested in multisite configurations. It’s on the roadmap…


How do I verify that the plugin is working?

Once, you have a converter, that works, when you click the “test”-button, you are ready to test the whole stack, and the rewrite rules. To do this, first make sure to select something other than “Do not convert any images!” in Image types to convert. Next, click “Save settings”. This will save settings, as well as update the .htaccess.

If you are working in a browser that supports webp (ie Google Chrome), you will see a link “Convert test image (show debug)” after a successful save. Click that to test if it works. The screen should show a textual report of the conversion process. If it shows an image, it means that the .htaccess redirection isn’t working. It may be that your server just needs some time. Some servers has set up caching. It could also be that your images are handled by nginx.

Note that the plugin does not change any HTML. In the HTML the image src is still set to ie “example.jpg”. To verify that the plugin is working (without clicking the test button), do the following:

  • Open the page in 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”

In order to test that the image is not being reconverted every time, look at the Response headers of the image. There should be a “X-WebP-Convert-Status” header. It should say “Serving existing converted image” the first time, but “Serving existing converted image” on subsequent requests (WebP-Express is based upon WebP Convert).

You can also append ?debug after any image url, in order to run a conversion, and see the conversion report. Also, if you append ?reconvert after an image url, you will force a reconversion of the image.

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/
  • If you are up to it, you can try to get one of the local converters working. Check out this page on the webp-convert wiki
  • Finally, if you have access to a server and are comfortable with installing projects with composer, you can install webp-convert-cloud-service. It’s open source.
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 asure 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!

I am on NGINX / OpenResty

It is possible to make WebP Express work on NGINX, but it requieres manually inserting redirection rules in the NGINX configuration file (nginx.conf). For standard wordpress installations, the following rules should work:

Note that the rules stated here previously had a bug: It had ” rather than “. The slightly slanted quotation mark does not work. Also, it used $request_uri, which contains the querystring, which resulted in errors when querystrings were supplied (ie ?debug)

For 0.8.0:

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;

Beware: If you copy the code above, you might get an html-encoded ampersand before “wp-content”

For 0.7.0:

if ($http_accept ~* "webp"){
  rewrite ^/(.*).(jpe?g|png)$ /wp-content/plugins/webp-express/wod/webp-on-demand.php?source=$request_filename&wp-content=wp-content break;

Beware: If you copy the code above, you might get an html-encoded ampersand before “wp-content”

The wp-content argument must point to the wp-content folder (relative to document root). In most installations, it is ‘wp-content’.

Discussion on this topic here

I am on a WAMP stack

It has been reported that WebP Express almost works on WAMP stack. I’d love to debug this, but do not own a Windows server or access to one… Can you help?

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.

How do I make this work with a CDN?

Chances are that the default setting of your CDN is not to forward any headers to your origin server. But the plugin needs the “Accept” header, because this is where the information is whether the browser accepts webp images or not. You will therefore have to make sure to configure your CDN to forward the “Accept” header.

The plugin takes care of setting the “Vary” HTTP header to “Accept” when routing WebP images. When the CDN sees this, it knows that the response varies, depending on the “Accept” header. The CDN is thus instructed not to cache the response on URL only, but also on the “Accept” header. This means that it will store an image for every accept header it meets. Luckily, there are not that many variants for images:
– so it is not an issue.

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 setten 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
Owl Carousel 2

When is feature X coming?

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 loose plans ahead: The 0.9 release will add redirect rule in .htaccess (optionally), perhaps also include configurable destination. 0.10 will probably be some diagnose tool – this should release some time spend in the forum. 0.11 could be focused on PNG. 0.12 might be displaying rules for NGINX. 0.13 might be supporting Save-Data header (send extra compressed images to clients who wants to use as little bandwidth as possible). 0.14 might be multisite support. 0.15 might be a file manager-like interface for inspecting generated webp files. 0.16 might be WAMP support. This is all guessing. I’m only planning one milestone at the time. You can follow the issue queue here: https://github.com/rosell-dk/webp-express/issues

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, you can leave a wish. I shall take these wishes into account when prioritizing between new features.

How do I buy you a cup of coffee?

Easy enough! – Go here!


Quick & Easy

I’ve tried a few other webp converters and not had much success with them, and doing it through the root is more hassle than it needs to be, so Webp express is a real breath of fresh air and definitely a go-to plugin for optimisation. Thank you for making & maintaining it!


Can be a little confusing while trying to tell if it’s actually working or not but once you realize it is… you realize how awesome this plugin is.
Adding this to my “must have” list for all WP sites.

So easy I didn’t believe it could work

I had tried some more popular webp converting plugins and had nothing but difficulties and ultimately I couldn’t use them because my shared hosting wouldn’t support the apache requirements. By chance I stumbled across WebP Express in a blog post. The installation was so easy and I chose to pay 99 cents and buy eWWW to make it work and this was also straightforward. Ironically eWWW offers the same function as a plugin also but I couldn’t get it to work for me. I did have to contact the creator/helpdesk a couple of times with the same requests as others – namely that I was unable to verify whether it was actually working. The helpdesk was quick to respond and with good and knowledgeable advice and I am now confident that it is working as I have checked via another source. With a bit more UI I think this could be a very successful plugin and I wish the creator the best of luck in the future.

Good if you don’t have root access

One issue with web-p is that you often need root access in order to get the executable onto your server. This plugin helps you connect and setup WebP via remote server connections.

Great plugin

What a great plugin!

Install, setup and forget.

And Google will thank you for the fast loading web pages (SEO)

Read all 7 reviews

Contributors & Developers

“WebP Express” is open source software. The following people have contributed to this plugin.


Translate “WebP Express” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.



  • Fixed javascript bug


  • 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


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


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.


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


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


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)
  • 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. 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