RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] # If images not found on development site, load from production RewriteCond %{REQUEST_URI} ^/wp-content/uploads/[^\/]*/.*$ RewriteRule ^(.*)$ https://www.example.com/$1 [QSA,L]
The problem here is that “If images not found on development site” then the request has already been rewritten to index.php
by the preceding RewriteRule
(WordPress front-controller), so your rule block that follows does nothing.
NB: Whilst you’ve not explicitly included the R
(redirect
) flag on the RewriteRule
, this will implicitly trigger an external 302 (temporary) redirect, the same as if you had explicitly included R=302
on the directive. Explicitly including this flag is preferable to more clearly communicate its intent. In fact, you might want to change this to a 301 so that images are cached, thus preventing external redirects to your production server on every request.
The QSA
flag is not required here, since you are not including a query string on the RewriteRule
susbstitution.
Aside: Your RewriteRule
arguably matches too match… it matches everything, not just images, is that intentional?
You could resolve this by either…
-
preventing all image URLs being processed by the front-controller. For example, add an additional condition to the WP front-controller to exclude images:
RewriteCond %{REQUEST_URI} !\.(jpe?g|png|gif)$ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L]
-
OR, move your redirect to above the WP front-controller, and check for the non-existence of the requested file before redirecting to your production server. I would also be more restrictive on the regex and match only images (as mentioned above) – if that is the intention. For example:
RewriteRule ^index\.php$ - [L] # If images not found on development site, load from production RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^wp-content/uploads/[^/]+/.+\.(jpe?g|png|gif)$ https://www.example.com/$0 [R=302,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L]
The additional condition is not required, as you can perform the URL comparison in the RewriteRule
pattern (more efficient). The slash does not need to be escaped in the character class (or anywhere for that matter). And the QSA
flag is not required here (as mentioned above).
Note that the regex matches URL-paths of the form /wp-content/uploads/<somedirectory>/<something>.jpg
, where <something>
can be any number of additional subdirectories. This is based on your regex.
The $0
backreference (as opposed to $1
in your original directive) is the entire URL-path that is matched by the RewriteRule
pattern. $1
contains the first captured subgroup. In the revised directive, the first captured subgroup contains just the image file extension.