We’ve recently had some issues with a staging site being down and it turned out the reason for this was: In the words of Brad at Pixel and Tonic, the redirect is "intercepting the update request for the plugin causing Craft to no longer think it's a POST request”.

caused by:

# make sure index.php is always removed from url (google analytics   tracks duplicate)
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+index\.php(/[^\s\?]+)? [NC]
RewriteRule ^ %1 [L,R=301]

we also have in all our craft sites the normal CRAFT removal of index.php from the urls:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ index.php%{REQUEST_URI} [L,NC]

Essentially, a lot of our sites are existing sites that we redesigned and developed, so the .htaccess files contain a lot of redirects for analytics. We noticed that google analytics started tracking duplicate URLs (duplicate being some contained index.php). After some investigation, I found out that the URLs containing index.php were from redirects (although none of the redirect rules contained index.php).

So in order to make sure no urls ever contain index.php, I added the above mentioned rule. However, we learnt the hard way that that doesn’t work with Craft.

What recommendations do you have in order to never have index.php in URLs? I realize that the standard rewrite rule that the Craft CMS comes with is good enough to hide/remove the index.php from the url and you will normally only see the index.php in the url if you type it in manually - but for some reason, it does show up sometimes when people land on a redirect url which messes with the analytics data.

The way we got around it in the end was asking the folks that take care of the analytics to merge the URLs, which ended up being easy enough to do. I was just wondering if there was any other way?

3 Answers 3


This came up in the Craft Slack not so long ago. You'd want something like this...

# ------------------------------------------------------------
# Remove index.php
# ------------------------------------------------------------

RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !^/index\.php/admin\b [NC] # Don't mess with admin requests
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]

# ---------------------------------------------------------------------   -
# Send would-be 404 requests to Craft (standard Craft rewrite method)
# ----------------------------------------------------------------------

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) /index.php?p=$1 [QSA,L]

As another option that I usually do in addition to .htaccess, is to also add this to the array in craft/config/general.php file, and it'll stop Craft from ever adding the index.php.

'omitScriptNameInUrls' => true

Doing it this way prevents Craft from ever adding in the index.php to redirects, I believe.

  • Thanks Taylor. We always have 'omitScriptNameInUrls' => true, with my limited knowledge of craft, i was under the impression that this is just part of hiding index.php from the url. Commented Sep 29, 2015 at 23:30
  • Correct, it tells Craft not to add the index.php to the URLs. As long as you have Craft's redirect in your .htaccess, you should be good. If you're interested, you can actually see what the parameter is doing by checking out craft/app/etc/config/defaults/general.php. Commented Sep 30, 2015 at 15:05
  • Another thing ( that isn't mentioned in the docs craftcms.com/support/remove-index.php ) is that if Craft has cached your links with index.php in them you'll need to do a Settings > Clear Cache to generate new links without the index.php
    – Davey
    Commented Aug 16, 2017 at 15:13
  • Or during development, disable cache with 'devMode' => true, in craft/config/general.php
    – Davey
    Commented Aug 16, 2017 at 15:26

Don't forget to rewrite "?p=" as well...

# remove index.php
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !^/index\.php/admin\b [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]

# remove ?p=
RewriteCond %{THE_REQUEST} ^GET\ /\?(([^&\s]*&)*)p=([^&\s]+)&?([^\s]*)
RewriteRule ^(.*)$ /%3?%1%4 [L,R=301]

# send would-be 404 requests to craft
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?p=$1 [QSA,L]

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.