Resolve Missing Local Images Using .htaccess

Files and their related database are the body and soul of a website. Files are composed of source codes and its related assets (e.g. images, pdfs, CS/JS files, etc). Database contains some of the site's settings and configurations, user records and permissions, site contents, ans so on. You need both of them in order for the website to work as intended. As a developer, it's a usual task to setup your development/local copy using the database and files from the staging/production servers of a site. Site database is relatively easy to import, but the site assets are usually huge and harder to keep in sync. 

Recently, we have a chance to work with  CNN Arabic which is implemented also in Drupal. We utilized the given database, but we have to wait for the contents of the files folder to be sent to us. Our Dev server is under a Virtual Private Network (VPN) which requires us some special permission and is also kinda slow. While waiting for the files, we just opted to point our local assets in the Prod. Normally, I'll just use Stage File Proxy or CDN (if the site has CDN integration), but our co-developer in CNN Arabic pointed to us that we could probably use the .htaccess file also. He is right. Unlike CDN and Stage File Proxy, with .htaccess, you don't need to install additional modules and configure their admin settings. You just need to add 2 lines at a minimum.

The Power of .htaccess

.htaccess (hypertext access) is a special file used by web servers like Apache or Nginx. It is usually used to restrict the site pages and redirect some URLs. They're bundled with Drupal also by default. You could use that file to override the server behavior, and if you're executing PHP as an Apache module (mod_php), like in XAMPP, you could set also the PHP settings using it.

Redirection Kung Fu

Just insert lines 4 and 6 in the mod_rewrite section of your your .htaccess file:

<IfModule mod_rewrite.c>
  RewriteEngine on
  
  RewriteCond %{REQUEST_URI} \.(png|jpg|jpeg|gif|ico)$ [NC]

  RewriteRule ^ http://arabic.cnn.com%{REQUEST_URI} [L,R=301]

  ...
</IfModule>

Basically, we are saying that if the requested URL ends with ($) an image file extension (jpg, png, etc), and not being strict to case sensitivity (NC), we rewrite the URL by appending the relative path to the specified base URL, that is, http://arabic.cnn.com. L means it's the last rule and no need to proceed further; R means it's a redirection directive, and R=301 means that the redirection is permanent. For further details, see mod_rewrite cheat sheet.

You could also instruct your local server to just fetch images that it couldn't found locally, especially if you're uploading custom/test images in your local which have no counterpart in your remote servers. In line 5 below, we are adding another condition that instructs the redirection directive to take effect only if the image is not available locally.

<IfModule mod_rewrite.c>
  RewriteEngine on
  
  RewriteCond %{REQUEST_URI} \.(png|jpg|jpeg|gif|ico)$ [NC]
  RewriteCond %{REQUEST_FILENAME} !-f

  RewriteRule ^ http://arabic.cnn.com%{REQUEST_URI} [L,R=301]

  ...
</IfModule>

Moreover, if you have CDN integration in your site, it's better to utilize those URLs to avoid the additional HTTP requests in the Prod server. CDN is composed of servers that contain redundant copies of your site's assets and uses a method so that it will utilize the nearest available server in your location instead of requesting from the site's main server. 

<IfModule mod_rewrite.c>
  RewriteEngine on
  
  RewriteCond %{REQUEST_URI} \.(png|jpg|jpeg|gif|ico)$ [NC]
  RewriteCond %{REQUEST_FILENAME} !-f

  RewriteRule ^ http://i.cdn.turner.com/dr/cnnarabic/cnnarabic/release%{REQUEST_URI} [L,R=301]

  ...
</IfModule>

Image Rendering

After saving your changes, and reloading the page. Your images will still show the local URLs but will be redirected/rendered on-the-fly. But, you could verify the behavior by opening a local image's URL in a new tab: it will be redirected to the equivalent URL in prod.

Notes

  • You could redirect CSS and JS files also, not only images.
  • .htaccess redirection's ideas could be applied to any website using Apache/Nginx (WordPress, Joomla, Django, etc).
  • If you are using Git version control system in your site, make sure that you do not push your local changes in .htaccess upstream to the remote servers to prevent overriding their default configurations.
  • Recommended article for further reading.

Tags: