Delivering webp and avif doesn't work

Hey all,

I am on hestiacp, nginx, php fpm and wordpress.

I am trying to deliver webp and avif pictures.

I did many things that didn’t work, but here is the last thing I tried:

I added that:

  location ~ ^/wp-content/uploads/.*\.(png|jpe?g)$ {
    add_header Vary Accept;
    try_files $uri$avif_suffix$webp_suffix $uri$avif_suffix $uri$webp_suffix $uri =404;
  }

Inside the server directive of my wordpress template.

And then I added that:

  map $http_accept $webp_suffix {
    default        "";
    "~image/webp"  ".webp";
  }
  map $http_accept $avif_suffix {
    default        "";
    "~image/avif"  ".avif";
  }

Inside my http directive in my nginx.conf file.

But it did nothing. So I also tried to add that:

http {
  map $http_accept $webp_suffix {
    default        "";
    "~image/webp"  ".webp";
  }
  map $http_accept $avif_suffix {
    default        "";
    "~image/avif"  ".avif";
  }
}

At the top of my wordpress template, but it also did nothing.

Do you have an idea why this doesn’t work?

Thanks in advance!

I haven’t enabled for avid yet but this works for .webp

   map $http_accept $webp_suffix {
       "~*webp"  ".webp";
    }

And

	        location ~ ^/wp-content/.*\.(png|jpe?g)$ {
                        root        %sdocroot%;
			expires     max;
                        add_header Vary Accept;
                        try_files $uri$webp_suffix $uri =404;
                }

Thanks for your answer, how did you add that?

I’ve added:

 location ~ ^/wp-content/.*\.(png|jpe?g)$ {
                        root        %sdocroot%;
			expires     max;
                        add_header Vary Accept;
                        try_files $uri$webp_suffix $uri =404;
                }

In my wordpress template inside the server directive

And for that:

  map $http_accept $webp_suffix {
       "~*webp"  ".webp";
    }

I tried both in an http directive in my wordpress template and in the http directive of the nginx.conf but I couldn’t make it work :frowning:

(no syntax error, just wordpress doesn’t delivering webp)

Make sure to clear your browser caches.

Hestia can be a bit picky with that …

Also please not it doesn’t change extension of the file:

But it should show webp instead of jpg…

I did clear all my caches, but I tried again and I cleared all of them once more and I even rebooted my server but yeah in “type” in “inspect element” I still have jpeg/jpg/png

I really don’t know what’s wrong, I’m on a fresh install and I might have tried almost all the codes available on the internet + chatgpt ones :frowning:

Maybe try

wordpress-webp.tpl

#=========================================================================#
# Default Web Domain Template                                             #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
# https://hestiacp.com/docs/server-administration/web-templates.html      #
#=========================================================================#

server {
	listen      %ip%:%web_port%;
	server_name %domain_idn% %alias_idn%;
	root        %docroot%;
	index       index.php index.html index.htm;
	access_log  /var/log/nginx/domains/%domain%.log combined;
	access_log  /var/log/nginx/domains/%domain%.bytes bytes;
	error_log   /var/log/nginx/domains/%domain%.error.log error;

	include %home%/%user%/conf/web/%domain%/nginx.forcessl.conf*;

        location ~* ^(/wp-content/.+)\.(png|jpe?g)$ {
		set $base $1;
		set $webp_uri $base$webp_suffix;
		set $webp_old_uri $base.$2$webp_suffix;
		set $root "%docroot%";
		root $root;
		add_header Vary Accept;
		if ( !-f $root$webp_uri ) {
			add_header X_WebP_SP_Miss $root$webp_uri;
		}
		try_files $webp_uri $webp_old_uri $uri =404;
	}

	location = /favicon.ico {
		log_not_found off;
		access_log off;
	}

	location = /robots.txt {
		try_files $uri $uri/ /index.php?$args;
		log_not_found off;
		access_log off;
	}

	location ~ /\.(?!well-known\/) {
		deny all;
		return 404;
	}

	location / {
		try_files $uri $uri/ /index.php?$args;

		location ~* ^.+\.(ogg|ogv|svg|svgz|swf|eot|otf|woff|woff2|mov|mp3|mp4|webm|flv|ttf|rss|atom|jpg|jpeg|gif|png|webp|ico|bmp|mid|midi|wav|rtf|css|js|jar)$ {
			expires 30d;
			fastcgi_hide_header "Set-Cookie";
		}

		location ~* /(?:uploads|files)/.*.php$ {
			deny all;
			return 404;
		}

		location ~ [^/]\.php(/|$) {
			try_files $uri =404;

			include /etc/nginx/fastcgi_params;

			fastcgi_index index.php;
			fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

			fastcgi_pass %backend_lsnr%;

			include %home%/%user%/conf/web/%domain%/nginx.fastcgi_cache.conf*;

			if ($request_uri ~* "/wp-admin/|/wp-json/|wp-.*.php|xmlrpc.php|index.php|/store.*|/cart.*|/my-account.*|/checkout.*") {
				set $no_cache 1;
			}

			if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash|PHPSESSID") {
				set $no_cache 1;
			}
		}
	}

	location /error/ {
		alias %home%/%user%/web/%domain%/document_errors/;
	}

	location /vstats/ {
		alias   %home%/%user%/web/%domain%/stats/;
		include %home%/%user%/web/%domain%/stats/auth.conf*;
	}

	include /etc/nginx/conf.d/phpmyadmin.inc*;
	include /etc/nginx/conf.d/phppgadmin.inc*;
	include %home%/%user%/conf/web/%domain%/nginx.conf_*;
}

wordpress-webp.stpl

#=========================================================================#
# Default Web Domain Template                                             #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
# https://hestiacp.com/docs/server-administration/web-templates.html      #
#=========================================================================#

server {
	listen      %ip%:%web_ssl_port% ssl;
	server_name %domain_idn% %alias_idn%;
	root        %sdocroot%;
	index       index.php index.html index.htm;
	access_log  /var/log/nginx/domains/%domain%.log combined;
	access_log  /var/log/nginx/domains/%domain%.bytes bytes;
	error_log   /var/log/nginx/domains/%domain%.error.log error;

	ssl_certificate     %ssl_pem%;
	ssl_certificate_key %ssl_key%;
	ssl_stapling        on;
	ssl_stapling_verify on;

	# TLS 1.3 0-RTT anti-replay
	if ($anti_replay = 307) { return 307 https://$host$request_uri; }
	if ($anti_replay = 425) { return 425; }

	include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*;

	location ~* ^(/wp-content/.+)\.(png|jpe?g)$ {
		set $base $1;
		set $webp_uri $base$webp_suffix;
		set $webp_old_uri $base.$2$webp_suffix;
		set $root "%sdocroot%";
		root $root;
		add_header Vary Accept;
		if ( !-f $root$webp_uri ) {
			add_header X_WebP_SP_Miss $root$webp_uri;
		}
		try_files $webp_uri $webp_old_uri $uri =404;
	}

	location = /favicon.ico {
		log_not_found off;
		access_log off;
	}

	location = /robots.txt {
		try_files $uri $uri/ /index.php?$args;
		log_not_found off;
		access_log off;
	}

	location ~ /\.(?!well-known\/) {
		deny all;
		return 404;
	}

	location / {
		try_files $uri $uri/ /index.php?$args;

		location ~* ^.+\.(ogg|ogv|svg|svgz|swf|eot|otf|woff|woff2|mov|mp3|mp4|webm|flv|ttf|rss|atom|jpg|jpeg|gif|png|webp|ico|bmp|mid|midi|wav|rtf|css|js|jar)$ {
			expires 30d;
			fastcgi_hide_header "Set-Cookie";
		}

		location ~* /(?:uploads|files)/.*.php$ {
			deny all;
			return 404;
		}

		location ~ [^/]\.php(/|$) {
			try_files $uri =404;

			include /etc/nginx/fastcgi_params;

			fastcgi_index index.php;
			fastcgi_param HTTP_EARLY_DATA $rfc_early_data if_not_empty;
			fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

			fastcgi_pass %backend_lsnr%;

			include %home%/%user%/conf/web/%domain%/nginx.fastcgi_cache.conf*;

			if ($request_uri ~* "/wp-admin/|/wp-json/|wp-.*.php|xmlrpc.php|index.php|/store.*|/cart.*|/my-account.*|/checkout.*") {
				set $no_cache 1;
			}

			if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash|PHPSESSID") {
				set $no_cache 1;
			}
		}
	}

	location /error/ {
		alias %home%/%user%/web/%domain%/document_errors/;
	}

	location /vstats/ {
		alias   %home%/%user%/web/%domain%/stats/;
		include %home%/%user%/web/%domain%/stats/auth.conf*;
	}

	proxy_hide_header Upgrade;

	include /etc/nginx/conf.d/phpmyadmin.inc*;
	include /etc/nginx/conf.d/phppgadmin.inc*;
	include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}

I am not sure if it it adds the suffix or not…

Thanks! It seems that it doesn’t add webp (added the template, restarted my serv, clear all my caches, but nothing)

BTW just to be sure, I want to say that It didn’t added the webp suffix (I had a syntax error) so I added it right there:

Otherwise the template is correctly activated, my caches are cleared, the serv is restarted, I really don’t know where to look at :confused: it was working on the same wordpress backup but with the nginx + apache config (with htaccess), so I don’t think that my wordpress is a problem

Hi @eris I am having trouble with this.

I am trying to implement a per-domain config just by adding a nginx.conf_webp file.

nginx.conf_webp:

# Optimización de imágenes habilitada para {DOMAIN}
location ~* \.(jpe?g|png)$ {
    try_files $uri.webp $uri =404;
}

I move the file to the correct path. I sed to substitute {DOMAIN} with the domain

Then I test with nginx -T | grep “domain.com” and I see that the config has been loaded BUT I dont get the correct file with wget.

Can you please help me with this?

I don’t know if I’m allowed to resurrect an old thread.
I’ve been chasing my tail on webp conversions since day 1.

I finally got this error message on WP-Optimizely

Required WebP shell functions are not available on the server.

When I googled this, this was the first thing that came up

I had disabled a number of PHP functions on the advice of a security tutorial and it turns out that the following functions are necessary to create a WebP version of the image:

passthru
shell_exec
system
proc_open

Is it possible to turn these on and off during conversion or something?
I don’t know how to do this. I assume php.ini, I’m a bit confused about how to override php.ini on a site-by-site basis?

I’m really BAD with php. But it’s my lifeblood.

You cannot override php.ini on a site by site basis. At least, I am not aware. If you need to enable these functions then you will need to do it at the server wide configuration.

To do so, open the file /etc/php/VERSION/fpm/php.ini where ‘VERSION’ is the version number of PHP you are using. Find the line disable_functions= and remove those functions from it. Save the file and restart PHP.

Last, you are not really allowed to revive old threads so next time probably open a new thread and reference an old if you need to.

Good Luck!

i think you CAN override php.ini on a site by site basis, through a work around: Have your sites use slightly different versions of php, (7.4,8.1,8.2 etc) and then edit each of the php.ini which each version uses. It seems to me that that should, in theory, do the trick.