Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I would like to redirect index.php, as well as any other valid default file (e.g. index.html, index.asp, etc.) to the document root (which contains index.php) with something like this:

RewriteRule ^index\.(php|htm|html|asp|cfm|shtml|shtm)/?$ / [NC,L]

However, this is of course giving me an infinite redirect loop. What's the right way to do this?

If possible, I'd like to have this work in both the development and production environment, so I don't want to specify an explicit url like as the target.


share|improve this question

In case someone finds this, here's how I use it for production and development.

# index.php to root
RewriteCond %{HTTP_HOST} ^localhost [NC]
RewriteRule ^index\.(php|htm|html)/?$ /SiteFolder/ [R=301,NC,L]

RewriteCond %{HTTP_HOST} !^localhost [NC]
RewriteRule ^index\.(php|htm|html)/?$ / [R=301,NC,L]

Add extensions as you need, separating with |

share|improve this answer

I think something like this should work. Running off to a meeting, so i don't have time to test it, but basically you have to set condition not to redirect main

RewriteEngine On
RewriteCond !^/index.php
RewriteRule ^index\.(php|htm|html|asp|cfm|shtml|shtm)/?$ / [NC,L]
share|improve this answer
@solefald - Thanks for the shot, that still doesn't seem to work. (I get a server 500 error with the following: RewriteCond !^index.php RewriteRule ^index\.(php|htm|html|asp|cfm|shtml|shtm)/?$ /ri2/ [NC,L] (/ri2 is my development directory). I also tried escaping the . and using ^/index\.php but still get 500. Also, how would I rewrite for index.php itself? Thanks for any advice. – user41138 Apr 22 '10 at 14:13
Try adding $1 after /ri2/. RewriteRule ^index\.(php|htm|html|asp|cfm|shtml|shtm)?$ /ri2/$1. Also you may want to enable mod_rewrite logging, but it wont work out of .htaccess, you need to put it into httpd.conf or whatever config your apache is using. RewriteEngine on RewriteLog /tmp/rewrite.log RewriteLogLevel 3 – solefald Apr 22 '10 at 15:22

You can try 301 redirecting it. This should be theoretically search engine friendly.

RewriteRule ^index\.(php|htm|html|asp|cfm|shtml|shtm)/?$ / [R=301,L]
share|improve this answer
Well, I don't know very much about server configuration (that's why I need you guys), but I do know SEO. Your statement is inaccurate; 301s DO LOSE PR: (see matt cutts interview with Eric Enge 1/25/10: "There is some loss of PR through a 301". – user41138 Apr 22 '10 at 14:07
Probably not all Google employees are unanimous ( ;-) But I'm not a SEO specialist, so I won't argue here. The point is - even if you lose some PR (it's same domain here, so I'm not sure if that's what Eric meant), what's the correct way to do it? I supposed your goal is to redirect all requests to root - not to allow access to the main page through .htm/.html/... (duplicate content?). Maybe I misunderstood you here. – Karol Piczak Apr 22 '10 at 15:34

I am certain that Karol's solution is correct (the RewriteCond in solefald's solution is unnecessary), and respectfully dispute TMG's rebuttal regarding PageRank.

First, SEO and PageRank: while it is true that Matt Cutts has indicated that a 301 redirected page is not (quite) as powerful as a direct link, the condition that needs to be corrected here relates to duplicate content. If the site with /index.php and the site with / result in the same page, this is duplicate content, and (especially with the home page of a site) is an important consideration: a given page should always have one and only one URL, the "canonical" URL for a page.

At best, Google will ignore whichever one it decides it should. At worst, it will index both and sites linking to one variant will pass PR to that variant, and those linking to the other will pass their PR to the other. You should get all pages to link to one (and the one should be /).

Karol's solution above is correct (you do not need a RewriteCond) with one minor note: if you are editing a .htaccess file, it's right as written; if you are editing in the server configuration file or VirtualHost context, you'll need to add a slash first

RewriteRule ^/index\.(php|htm|html|asp|cfm|shtml|shtm)/?$ / [R=301,L]

or to make this work in either context, use the ? regex operator to say "possibly a slash":

RewriteRule ^/?index\.(php|htm|html|asp|cfm|shtml|shtm)/?$ / [R=301,L]

A final additional point: make sure in your configuration (either server, virtualhost or .htaccess) you specify at least:

DirectoryIndex index.php
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.