FREE THOUGHT · FREE SOFTWARE · FREE WORLD

.htaccess trick to show Alternate CSS file based on IP

This past week I was making changes to my sites apache.css file for a site-redesign. I wanted to make changes to the .css file that only I could see, so that my regular traffic and site-visitors would still see the old version. I quickly came up with an elegant solution using the incredibly powerful .htaccess and mod_rewrite that worked so well I wanted to share it with all you great and interesting people :)


Why and How to Use

So to develop the new site's css file I created a new file on my server called apachenew.css, and the old file was called apache.css, this trick simply shows anyone accessing the site from a certain IP address the apachenew.css file instead of the apache.css file. Cool huh!?! So I can edit the apachenew.css file and preview the site with the new css while everyone else still sees the old css. When I am finished I just save apachenew.css as apache.css and remove this .htaccess code. Sweet!


Updated: I got some emails from you all asking for a clearer ready-to-use example, especially from WordPress bloggers. Here you go!

.htaccess code for WordPress

Ok find your .htaccess file

# BEGIN WordPress
<ifModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</ifModule>

# END WordPress

The New htaccess

This is assuming that your themes real .css file is /wp-content/themes/yourtheme/stylesheet.css and the developer .css file you will only be able to see is located at /wp-content/themes/yourtheme/stylesheet-new.css

<files stylesheet-new.css>
<ifModule mod_headers.c>
Header set Cache-Control "must-revalidate, no-store, no-cache"
</ifModule>
</Files>

RewriteEngine On
RewriteBase /

RewriteCond %{REMOTE_ADDR} =208.113.134.190
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /wp-content/themes/yourtheme/stylesheet.css.* HTTP/ [NC]
RewriteRule ^wp-content/themes/yourtheme/stylesheet.css$ /wp-content/themes/yourtheme/stylesheet-new.css [L]

# BEGIN WordPress
<ifModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</ifModule>

# END WordPress

Note: The real filename is apache.css, the -0031 part is because I use the incredibly useful mod_rewrite updated file caching techinque which allows me to force clients to use updated versions of my .css file by renaming it, while at the same being able to set Far Future Expires Headers for optimum caching.


Changes to XHTML

None! The link to include my .css file within the <head></head> of my pages XHTML remains the same.

<link rel="stylesheet" type="text/css" href="https://www.askapache.com/s/s.askapache.net/z/c/apache-0031.css" />

.htaccess code to show alternate .css file based on IP

So my browser makes a request for the apache-0031.css file, and IF the request originates from the IP address 208.113.134.190 then this code will instead serve the apachenew.css file AND then it uses the S=1 RewriteRule flag to skip over the next RewriteRule Block, which is my updated file caching techinque trick. If you don't use that you won't need to skip any rules or use the 2nd RewriteRule block below, just the first.

RewriteEngine On
RewriteBase /

RewriteCond %{REMOTE_ADDR} =208.113.134.190
RewriteCond %{THE_REQUEST} ^(GET|HEAD) /z/c/apache-([0-9]+).css.* HTTP/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^z/c/apache-([0-9+]).css$ /z/c/apachenew.css [L,S=1]

RewriteCond %{THE_REQUEST} ^(GET|HEAD) /z/([cj]+)/(.+)-([0-9]+).(js|css).* HTTP/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^z/([cj]+)/.*.(css|js)$ /z/%2/%3.%5 [NC,L]

Turn OFF Caching for Development CSS

The next thing I wanted to automate was to turn off the caching of the apachenew.css file, which only I can see so there is no need to cache. To do this with my current caching scheme I simply add the must-revalidate header to the headers sent for that file.

<files apachenew.css>
<ifModule mod_headers.c>
Header set Cache-Control "must-revalidate"
</ifModule>
</Files>

What do you think? Questions/Improvements/Comments Welcome!

Htaccess

Comments