1

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?

1 Answer 1

2
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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the solution and detailed explanation. I tested it and it's working fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.