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

<pre><code># ------------------------------------------------------------
# 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]
</code></pre>

CC BY-SA 3.0
2015-09-23T05:02:55.590Z
2015-09-23T05:02:55.590Z
Jamie Pittock
<p>As another option that I usually do in addition to <code>.htaccess</code>, is to also add this to the array in <code>craft/config/general.php</code> file, and it'll stop Craft from ever adding the <code>index.php</code>.</p>

<p><code>'omitScriptNameInUrls' =&gt; true</code></p>

<p>Doing it this way prevents Craft from ever adding in the <code>index.php</code> to redirects, I believe.</p>

CC BY-SA 3.0
2015-09-29T23:30:21.433Z
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.
Lee Jacobsz
CC BY-SA 3.0
2015-09-30T15:05:34.160Z
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`.
Taylor Daughtry
CC BY-SA 3.0
2017-08-16T15:13:07.317Z
Another thing ( that isn't mentioned in the docs https://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
CC BY-SA 3.0
2017-08-16T15:26:37.803Z
Or during development, disable cache with `'devMode' => true,` in `craft/config/general.php`
Davey
CC BY-SA 3.0
2015-09-23T13:33:38.993Z
2015-09-23T13:33:38.993Z
Taylor Daughtry
<p>Don't forget to rewrite "?p=" as well...</p>

<pre><code># 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\ /\?(([^&amp;\s]*&amp;)*)p=([^&amp;\s]+)&amp;?([^\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]
</code></pre>

CC BY-SA 4.0
2018-11-15T23:25:53.567Z
2018-11-15T23:25:53.567Z
Leo Leoncio
<p>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 <strong>"intercepting the update request for the plugin causing Craft to no longer think it's a POST request”.</strong></p>

<p>caused by:</p>

<pre><code># 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]
</code></pre>

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

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

<p>Essentially, a lot of our sites are existing sites that we redesigned and developed, so the <code>.htaccess</code> 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).</p>

<p>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.</p>

<p>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.</p>

<p>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?</p>

<url><craft-pro><htaccess><analytics>
redirect index.php in urls on Craft site to NEVER show index.php
# redirect index.php in urls on Craft site to NEVER show index.php

(Asked by: username_0 on 2015-09-22)

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?

**Tags:** url, craft-pro, htaccess, analytics

---

## 3 answers

### Answer by username_1 on 2015-09-23. Score: 4 | Accepted answer

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]


---

### Answer by username_2 on 2015-09-23. Score: 5

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.

> **Comments:**
> **username_0**: 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.  
> **username_2**: 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`.  
> **username_3**: Another thing ( that isn't mentioned in the docs https://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`  
> **username_3**: Or during development, disable cache with `'devMode' => true,` in `craft/config/general.php`  

---

### Answer by username_4 on 2018-11-15. Score: 2

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]


---

