Home > Back-end >  Redirect only root index.php to root in .htaccess, not index.php from subdirectories
Redirect only root index.php to root in .htaccess, not index.php from subdirectories

Time:12-04

I need to make some SEO adjustments on a 10 years old code base so I have to proceed with caution.

The task is to do a 301 redirect of https://www.example.com/index.php to https://www.example.com.

The current rules are these:

DirectoryIndex index.php
RewriteEngine On
RewriteBase /

# Force WWW
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]

# Force HTTPS
RewriteCond %{HTTPS} !on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]

# Add a trailing slash to non-files
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301,NE]

# General rules
RewriteRule ^product/(.*)-(.*)/(.*)-(.*)/$ product.php?category_permalink=$1&category_id=$2&product_permalink=$3&product_id=$4 [QSA,L]
RewriteRule ^categories/(.*)-(.*)/page-(.*)/$ categories.php?permalink=$1&category_id=$2&page=$3 [QSA,L]
RewriteRule ^categories/(.*)-(.*)/$ categories.php?permalink=$1&category_id=$2 [QSA,L]
RewriteRule ^categories/$ categories.php [QSA,L]
RewriteRule ^search/(.*)$ search.php?q=$1 [QSA,L]

I tried adding the following rules and it works fine, but it messes up https://www.example.com/admin/ too and the website admin can't login anymore because of that.

RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ /$1 [R=301,L]

So what I'm trying to figure out is: how can I do the redirect only for the index.php file in the root, not for other subdirectories?

Is this possible?

CodePudding user response:

RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ /$1 [R=301,L]

The .* subpattern matches any URL-path that precedes index.php, so you basically need to remove that.

However, since you don't appear to be using a front-controller pattern (ie. rewriting the request to /index.php) you don't need the preceding condition.

The following would suffice (placed immediately after the RewriteBase directive and before your existing rules - in order to minimise redirects):

RewriteRule ^index\.php$ https://www.example.com/ [R=301,L]

You will need to clear your browser cache before testing. Preferably test with 302 (temporary) redirects to avoid potential caching issues.


If you wish to make this rule generic and avoid hardcoding the hostname (like your other rules) then you can change it like so:

RewriteCond %{HTTP_HOST} ^(?:www\.)?(. ?)\.?$ [NC]
RewriteRule ^index\.php$ https://www.%1/ [R=301,L]

The %1 backreference contains the hostname, less the www. subdomain (if any), as captured in the preceding condition.


You can "simplify" the rule and omit the absolute URL (making it root-relative). For example:

RewriteRule ^index\.php$ / [R=301,L]

However, this will result in two redirects if requesting the non-canonical hostname or protocol (ie. non-www or HTTP). Not that that should necessarily cause a serious issue, particularly if non-canonical requests are rare.

CodePudding user response:

If you're using Apache then it would be in your httpd.conf where you can change that.

  • Related