Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

milroy's avatar

301 redirect to non index.php url

Laravel allows to visit a page with /index.php. How to remove and [301] redirect to page without /index.php

e.g. abc.com/index.php/contact to abc.com/contact

My current .htaccess

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On
    
    # Redirect www to non-www
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
0 likes
33 replies
milroy's avatar

Thanks @mstnorris. it's really helpful. But still there's a small issue. It redirects to the base url e.g. abc.com/index.php/contact redirects to abc.com. I need it to be redirected to abc.com/contact

milroy's avatar

this doesn't work :(

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>
    
    Options +FollowSymLinks -MultiViews

    RewriteEngine On
    
    # Redirect www to non-www
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
    RewriteRule ^ %1 [R=301,L]
</IfModule>
mstnorris's avatar

Maybe @bashy could weigh in on this one, it's over my head, I've never liked this as the syntax isn't friendly. This is a wild guess but I would remove the

``bash # Handle Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L]

bashy's avatar

This will redirect from www to non-www (put it directly after RewriteEngine On)

RewriteCond %{HTTP_HOST} ^www\.
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]

If it doesn't work, please post a cURL request for both www and non-www

milroy's avatar

tnx @bashy. I have no issues with redirection www to non-www only issue is I want to remove /index.php and [301] redirect to any url.

e.g.
abc.com/index.php/contact  to  abc.com/contact

It's a requirement from our SEO team.

@JeffreyWay any solution for this. Found lots of google indexed pages through /index.php site:laracasts.com/index.php

milroy's avatar

@bashy it redirects all requests to base url.

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>
    
    RewriteEngine On
    
    # Redirect www to non-www
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    
    RewriteRule ^index.php/?(.*)$ $1 [R=301,L]
</IfModule>
sitesense's avatar

Does this not work:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>
    
    RewriteEngine On
    
    # Redirect www to non-www
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    
</IfModule>

If not, try this too:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options +FollowSymLinks
    </IfModule>
    
    RewriteEngine On
    
    # Redirect www to non-www
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    
</IfModule>

http://laravel.com/docs/master#pretty-urls

EDIT: read again - removed a line from bottom example.

bashy's avatar

Why do you have RewriteBase / set? Comment that shit out :P

Also, you should be putting this DIRECTLY underneath RewriteEngine On

RewriteRule ^index.php/(.*)$ $1 [R=301,L]
milroy's avatar

Tnx all once again @mstnorris @bashy @sitesense really appreciate your support.

It looks like a common issue in all the websites built with laravel. even in

You can visit the same page from two urls. Which is an extra work for SEO guys and effects to the search engine ranking. I was trying to fix this issue via public/.htaccess . What is the best solution for this.

Really appreciate if you can look in to this @JeffreyWay @TaylorOtwell and make it happen in the core.

e.g.

http://laravel.com/index.php/docs/5.0  =  http://laravel.com/docs/5.0
https://laracasts.com/index.php/series  =  https://laracasts.com/series
https://oneplus.net/index.php/one  =  https://oneplus.net/one

query this on google "site:laracasts.com/index.php" so you can see already indexed duplicate content.

milroy's avatar

@bashy I have no idea about .htaccess syntax. I just added few lines to laravel default .htaccess to redirect all urls from www to non-www url, and it works.

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>
    
    RewriteEngine On
    
    # Redirect www to non-www
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

is it possible to modify the above code or write a new to full fill

  • Redirect www to non-www
  • Redirect Trailing Slashes
  • Handle Front Controller
  • REDIRECT any url which contains /index.php by repacing /index.php with "" (empty)
bashy's avatar

Yeah, put the code I posted directly below RewriteEngine On. I can't test it because I don't use Apache but if you have a test page, I can check it.

sitesense's avatar

@milroy whilst that's true to some extent, Google is sophisticated enough these days to understand the problem.

It just isn't an issue unless you start linking to content, or others start linking to content with abc.com/index.php/contact, which isn't going to happen.

Q: So how do I make sure that Google picks the url that I want?

A: One thing that helps is to pick the url that you want and use that url consistently across your entire site. For example, don’t make half of your links go to http://example.com/ and the other half go to http://www.example.com/ . Instead, pick the url you prefer and always use that format for your internal links.

https://www.mattcutts.com/blog/seo-advice-url-canonicalization/

milroy's avatar

@bashy I have updated my .htaccess files as follows

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>
    
    RewriteEngine On
    RewriteRule ^index.php/(.*)$ $1 [R=301,L]
    
    # Redirect www to non-www
    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

now when I visit

abc.com/index.php/contact
redirects to
abc.com/home5/www/public_html/mysite/public/contact
sitesense's avatar

query this on google "site:laracasts.com/index.php" so you can see already indexed duplicate content.

But if you query this site:laracasts.com you'll see that it can't be an issue because no links are turning up with index.php.

bashy's avatar

@milroy You have something strange going on :P how is it redirecting with the full path?!

Post your virtualhost as well...

milroy's avatar

@bashy it happens on justhost shared host :). I write a partial solution, but still I'm looking for a better solution [301] redirect.

<link rel="canonical" href="{{ str_replace('/index.php','',Request::url()) }}" />
bashy's avatar

If they can't work it out in support, I'd move host :P

Mushr00m's avatar

Hi, I'm having the same problem, I don't want my website to both work on domain.com and domain.com/index.php. I want to redirect everything to the version without index.php. I'm not sure to understand how did you handle it and isn't it the role of this line in the HTACCESS to do so :

RewriteRule ^ index.php [L]

Thanks

bashy's avatar

@james123 If your site never links to /index.php a user should never be on that link.

james123's avatar

@bashy yeah it never does, but a competitor has been going around and spamming /index.php links for Google to pick up :(

Next

Please or to participate in this conversation.