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