3

I'm trying to rewrite all website files (*.jpg|*.gif|*.png) to *.webp in a subdir, but only when the *.webp file exists. Previous and new files have the same name, only changing the extension and *.webp files are all under subdir of the original one.

I'm struggling with htaccess to do the job. Basic rules are:

  1. Only matches PNG/JPG/GIF file
  2. Original images dir pattern is: /site/views/00_projects/[VARIABLE MAIN DIR NAME HERE]/content/image/[VARIABLE SUBDIR NAME HERE]/*.jpg
  3. New *.webp dir is pattern is: /site/views/00_projects/[VARIABLE DIR NAME HERE]/content/image/[VARIABLE SUBDIR NAME HERE]/webp/*.webp
  4. Only rewrite IF webp file exists

I really have no idea on how to make it work. Can someone help?

MrWhite
  • 11,643
  • 4
  • 25
  • 40

1 Answers1

4

Strictly speaking you also need to make sure the user-agent making the request supports WEBP images (ie. check the Accept HTTP request header for image/webp).

Try the following near the top of the root .htaccess file:

RewriteEngine On

# Rewrite images to WebP if they exist
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/$1/webp/$2.webp -f
RewriteRule ^(site/views/00_projects/[^/]+/content/image/[^/]+)/([^/]+)\.(?:png|jpg|gif)$ $1/webp/$2.webp [T=image/webp,L]

The RewriteRule pattern (ie. ^(site/views/00_projects/[^/]+/content/image/[^/]+)/([^/]+)\.(?:png|jpg|gif)$) matches the requested png, jpg or gif image and saves the URL-path in the $1 backreference and the filename in the $2 backreference (used later in the RewriteRule substitution string).

The first condition (RewriteCond directive) that checks against the HTTP_ACCEPT server variable, checks that the user-agent supports WEBP images.

The second condition checks that the target webp image exists.

The T=image/webp flag is necessary to send the correct mime-type (Content-Type header) back to the client.

MrWhite
  • 11,643
  • 4
  • 25
  • 40
  • 1
    Worked like a charm, THANKS A LOT! One little question: with this code, the URL keeps the original file path (with *.jpg, i.e.); what would it need to redirect to *.webp url path if it exists and browser supports it? – Diego Flores Jul 24 '21 at 16:47
  • 2
    @DiegoFlores You're welcome. For a _permanent_ "redirect" you would add an `R=301` flag to the `RewriteRule` directive and you wouldn't then need the `T` flag. ie. `[R=301,L]`. However, you should generally avoid an external redirect if these are multiple in-page images, since it potentially slows your users (bad for SEO) and doubles the requests hitting your server, filling your logs with masses of 301s for what are "normal" requests. If you are linking to `.jpg` files etc. then keep it as an internal rewrite, otherwise, change the URLs you are linking to. – MrWhite Jul 24 '21 at 17:28
  • Thanks again! I'll keep it in mind! I was just wondering if Google will read the right Content-Type or only the file URL with the first solution when evaluating SEO/PageSpeed/etc ;-) Anyway, you saved the day <3 – Diego Flores Jul 24 '21 at 17:55
  • 1
    @DiegoFlores Yes, Google will read the "right Content-Type" - that's the purpose of the `T` flag. Whether the "URL" ends in `.jpg` (or whatever) is irrelevant - it is not the URL that determines the mime-type. – MrWhite Jul 25 '21 at 10:25
  • @DiegoFlores If this answered your question then please mark it as "accepted" by clicking the tick/checkmark next to the answer below the voting arrows (in order to help other readers). Thanks, much appreciated. :) – MrWhite Jul 25 '21 at 23:09