Leevi Graham — Monday 8th September, 12:06pm
LG .htaccess Generator - Removing index.php from your ExpressionEngine site
One constant frustration ExpressionEngine users have is, how do they easily remove index.php from their site.
The first point of call is usually “Remove index.php From Urls” documentation in the ExpressionEngine Wiki which lists three main methods and their caveats. The three methods listed in the wiki are:
Each method has their good and bad points which are listed below:
1. Include List Method
Good: Only affects ExpressionEngine template groups and pages.
Bad: Template groups and pages must be manually added to the .htaccess file each time a new one is created. This unfortunately is something that flies over the head of your average client.
2. Exclude List Method
Good: Client doesn’t have to do anything when a new template group or page is created.
Bad: Clients with FTP privileges will wonder why their new files they have uploaded into random directories are not working.
3. File and Directory Check Method
Good: Clients don’t have to worry about a thing when they upload new files or create templates and pages
Bad: If an image (or script or style sheet) tag references a missing file your site will end up calling an EE page, not a 404 page. This can be a massive negative impact on SEO and site performance.
The solution
The solution to this puzzle is included in the ExpressionEngine wiki although it’s not as flexible as it could be. The general idea is that the template groups list should be generated manually using an SQL query every time a new template or page is modified. Obviously not ideal.
Our solution - Introducing LG .htaccess Generator
Most of the current issues with ExpressionEngine can be squashed with a simple extension, in this case our solution is LG .htaccess Generator. LG .htaccess Generator automatically regenerates your .htaccess file every time a new page is created, a template group is modified (created, updated or deleted) or when the extension settings are saved. Simple.
Setting Up LG .htaccess Generator
The first thing you will need to do is download the LG .htaccess Generator extension from my personal site. On a side note; I’ll be moving all of my ExpressionEngine extensions, plugins and modules over to Newism as soon as I get a chance.
Once you have downloaded it, follow the instructions to install and setup the extension. One thing to remember is that you must have an existing .htaccess file already created and with write permissions in your site root.
The default .htaccess rules explained
I’ll just take a moment to explain each of the .htaccess rules in the default extension settings.
<Files .htaccess>
order allow,deny
deny from all
</Files>
Secure the .htaccess and stop malicious visitors viewing your .htaccess rules directly in the browser.
IndexIgnore *
Don’t list files in directory index pages.
ErrorDocument 404 /index.php?/{ee:404}
Point the standard 404 page to your ExpressionEngine 404 page. The {ee:404} tag will be replaced with your site’s 404 template group and template ie: site/404.
<FilesMatch "(\.jpe?g|gif|png|bmp)$">
ErrorDocument 404 "File Not Found"
</FilesMatch>
This rule overrides the previous 404 rule but just for requests that contain an image or file. It is important for site performance that a simple missing gif does not render a full ExpressionEngine page when it cannot be found.
# Remove the www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Rewrite homepage urls that have the Google Analytics query string. More information can be found here: Using URL rewrites to make ExpressionEngine, Campaign Monitor & Google Analytics play nice.
# Rewrite homepage urls that have the Google Analyticis query string
# CampaignMonitor adds the query string in their emails
# "site" is the template group
# "index" is the template name
# The template group and template should point to your sites index
RewriteCond %{QUERY_STRING} ^utm_medium
RewriteCond %{REQUEST_URI} ^/$ [NC]
RewriteRule (.*) /index.php?/site/index/&%{QUERY_STRING} [L]
Remove the www. from the URL and redirect the request to a non www. URL with a 301 Permanently Moved header. This rule avoids Google and other search engines indexing duplicate content.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule ^(.*)$ $1/ [L,R=301]
Add a trailing slash to the URL and redirect the request with a 301 Permanently Moved header. This rule also avoids Google and other search engines indexing duplicate content.
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5})$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/({ee:template_groups}|{ee:pages}|members|P[0-9]{2,8}) [NC]
RewriteRule (.*) /index.php?/site/index/&%{QUERY_STRING}
The grand-daddy of the .htaccess rules. This rule checks to see that the request does not end in an extension or is not an existing file. Then it checks the request to see if it contains one of our template groups or page URLs and internally redirects the request to be processed by ExpressionEngine.
The magic here is the {ee:template_groups} and {ee:pages} tags. Both of these tags will be replaced with ExpressionEngine data when the .htaccess file is generated. You should never need to manually update your .htaccess file again!
<FilesMatch "\.(html|htm|php)$">
Header set imagetoolbar "no"
</FilesMatch>
Finally we will remove that annoying IE image toolbar.
That’s about it
Well there you have it – LG .htaccess Generator – a simple to install and easy to use ExpressionEngine extension. If you use and enjoy this extension please consider sharing it with your friends on your chosen social network, bookmarking it on delicious.com or writing a blog post about it.
19/09/08 10:26am — The default settings of LG .htaccess Generator have been updated based on information in the post titled “Using URL rewrites to make ExpressionEngine, Campaign Monitor & Google Analytics play nice”.
22/09/08 9:31am — Tweaked the “remove www.” .htaccess rule.





Comments
The following 42 people were compelled to have their say. We encourage you to do the same.
Adam George said on Monday 15th September, 11:36pm: 1
Hi Leevi
Great extension! I just thought you’d like to know that you have the wrong alt attribute for the Wipa logo n your footer. I saw the logo and was interested in it, which is why I noticed.
Wayde Christie said on Tuesday 16th September, 9:58am: 2
@Adam - Thanks for the tip, and glad you enjoyed the article :)
giovanni said on Sunday 28th September, 7:28am: 3
Hiya- i just finished installing your extension hoping that after trying all kinds of fixes that I would finally be able to remove the index.php from the urls. No luck. I still have the index.php appearing. My urls look like this: www.example.com/index.php/contact etc… I looked at the .htaccess file and it was updated by your extension but is not having the desired effect. What now?
Leevi Graham said on Sunday 28th September, 2:41pm: 4
@giovanni – The plugin only generates the required .htaccess file. It doesn’t actually remove the index.php from the ExpressionEngine generated URLs.
To do that you will need to remove it in your system preferences. There is some more information in the wiki article which should put you on the right path.
giovanni said on Tuesday 30th September, 2:09pm: 5
bingo!
Duo said on Friday 3rd October, 5:08pm: 6
Hi Leevi,
Thanks for the great extension. I noticed a small issue when the .htaccess is being written to.
When I looked at the htaccess script, I noticed that it was generating an extra “|” right at the last onwer-generated template group name, which caused the entire site to display a 500 Internal Server Error. Here’s the copied script. When I delete the extra “|” character, everything works fine.
RewriteCond %{REQUEST_URI} ^/(site|search|contact|News||members|P[0-9]{2,8}) [NC]
Anything thoughts on how I can prevent this extra “|” from be written into the .htaccess file every time a new template is created?
Thanks—you’re the best!
duo.
ryolyo said on Saturday 4th October, 2:41pm: 7
I am struggling to implement this.
If I manually remove index.php from my urls in the browser, it works, and loads the proper templates.
This suggests the generated htaccess file is valid
But clicking any link loads an index.php url, so something is off. (maybe something in the EE cp?)
mod_rewrite is enabled on my server
I have installed the extension and double-checked the server root path.
Set up an .htaccess file in my root with 666 permissions, and verified that the file is being written to.
Set admin>sys prefs>gen config>”Name of your site’s index page” to blank
The htaccess template is greek to me, and I can’t identify anything I need to edit.
(I do have a custom name for my system directory, but I assume the ee variables take care of that.)
Is there anything I’m missing?
I don’t know where to go next
(I tried posting this to the forums, but couldn’t reply for some reason)
Thanks for any insight
giovanni said on Sunday 5th October, 5:43am: 8
@ryolyo see Leevi’s reply to my earleir post… edit your weblog paths in admin
Leevi Graham said on Sunday 5th October, 8:54pm: 9
@Everyone: If you have any problems getting LG .htaccess Generator up and running head on over to the ExpressionEngine support forums and add a new post. I’ll try and answer everyone over there.
ryolyo said on Monday 6th October, 3:24am: 10
You mean create a new thread?
I can’t reply to the ongoing one
http://expressionengine.com/forums/viewthread/90365/
Jonathan Schofield said on Saturday 3rd January, 8:32am: 11
Leevi, you may find this new thread of interest regarding member activation URLs: http://expressionengine.com/forums/viewthread/101112/.
You may have an Apache-based solution rather than my ugly hack!
Tom said on Thursday 12th February, 4:54am: 12
I had to comment out remove IE toolbar portion otherwise the server returned a 500 error.
Allan White said on Wednesday 11th March, 5:21pm: 13
@Tom - I also had issues with the IE toolbar section - same as you. I’m checking the EE forum thread, but wanted to note it here.
Kyle Pritchard said on Wednesday 18th March, 6:28am: 14
I had a few problems with linking my CSS files using this extension. To get around this problem add a few lines into the .htaccess rules:
#Sort Out CSS Problems
RewriteCond %{QUERY_STRING} ^(css=.*)$ [NC]
RewriteRule ^(.*)$ /index.php?/%1 [L]
Hopes this helps anyone with the same problem
Peter said on Monday 6th April, 5:20am: 15
Awesome plugin. But I still get an internal server error. I tried a lot of things, but it still won’t work. Help me please!
Luc said on Monday 13th April, 6:49pm: 16
Can this extension be used on a Windows server, using Helicon ISAP_Rewrite 3 and a httpd.conf file?
Luc said on Monday 13th April, 8:16pm: 17
Got it to work with httpd.conf, by changing one line of code:
Old: $file = $dir . “.htaccess”;
New: $file = $dir . “httpd.conf”;
You might add a setup-field “Name of .htaccess file” for this, so people don’t have to modify the code.
vlado varbanov said on Tuesday 12th May, 9:35pm: 18
I have a problem with linking a javascript templates in my site - after running the LG generator. Any solution ?
Farid said on Monday 1st June, 10:11am: 19
great !
Tom said on Wednesday 3rd June, 8:28am: 20
When I remove index.php from the General Configuration the ee contact form module no longer works. The form action no longer has the index.php so it’s just posting to / and not /index.php. Any idea how to resolve?
BridgingUnit said on Tuesday 16th June, 10:26pm: 21
If you alter the rules like so:
RewriteCond %{QUERY_STRING} !^(ACT=.*)$ [NC]
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5})$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/({ee:template_groups}|{ee:pages}|members|P[0-9]{2,8}) [NC]
RewriteRule (.*) /index.php?/site/index/&%{QUERY_STRING}
Then logging out and any other URLs that relay on the ?ACT= string to operate should work again. At least they do for me.
mhulse said on Monday 13th July, 4:23pm: 22
Hello,
Many thanks for this plugin! Very helpful. :)
I started a thread on Sitepoint that turned into a chat about the 404 ErrorDocument line:
http://www.sitepoint.com/forums/showthread.php?p=4315894&posted=1#post4315894
Not sure if I should be worried, but comment #7 piqued my interest (and concern):
[[
Now, about the ?. In regex, it’s a metacharacter meaning 0 or one of the preceding character (it has other meanings, too, but that would only confuse this issue). In a redirection (URI), it’s the marker for the start of the query string. Your use of index.php?/oops/ is so far out in left field that I’m not sure what you were intending (and Options MultiViews - using a filename in place of a directory name - only makes matters worse!). As I said, though, “if it ain’t broke, don’t fix it!”
— DK
]]
Where “/oops/index” is my designated template group 404.
DK (I think) is not familiar with EE, but he is an Apache guru. :)
Can someone clarify the usage of the ?, and should I be worried about the “Options MultiViews” comment?
Thanks!
M
Ryan said on Saturday 1st August, 9:39am: 23
You might want to amend the instructions to include when EE is installed in a subfolder.
Just alter these two lines:
RewriteBase /subfolder/
RewriteRule ^(.*)$ /subfolder/index.php?/$1 [L]
mike said on Monday 10th August, 11:23pm: 24
After the following code:
# Remove index.php
# Uses the “include method”
# http://expressionengine.com/wiki/Remove_index.php_From_URLs/#Include_List_Method
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5})$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $1 ^({ee:template_groups}|{ee:pages}members|P[0-9]{2,8}) [NC]
RewriteRule ^(.*)$ /index.php/$1 [L]
I have added the following line:
Redirect 301 http://www.mydomain/newsroom/newsroom.asp http://www.mydomain/newsroom
Because we have moved away from asp and onto expression engine I need to set up the redirects. Is there a special way I need to add these redirects? Any help appreciated.
Thank you
Gavin said on Monday 17th August, 2:57am: 25
Great plugin.. the only problem I am having is my 404 page is isn’t linking. It’s printing the path (site/404) in the code. I do have a page in my template group (site) and a template 404, but the page isn’t showing just the path. Any ideas?
# EE 404 page for missing pages
ErrorDocument 404 site/404
mhulse said on Thursday 20th August, 3:26am: 26
This is my setup:
# EE 404 page for missing pages
ErrorDocument 404 /index.php?/
# Other custom error pages:
ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
# Simple 404 for missing files
<FilesMatch “(\.jpe?g|gif|png|bmp)$”>
ErrorDocument 404 /errors/404.html
</FilesMatch>
Note: You have to go to your templates section, and setup your 404 via the global template prefs.
John said on Sunday 4th October, 3:05pm: 27
What if I want to send someone to a non-EE directory? I want to use phpBB on my site with the URL http://mysite.com/boards. Though the forum software is installed there, it shows the homepage.
Any ideas?
Nutmeg said on Wednesday 28th October, 7:54pm: 28
Could the Extension interfere with a Mint (haveamint.com) installation? When trying to update Mint’s preferences the redirected Url misses the index.php extension and no alterations to the preferences are registered……
Nutmeg said on Saturday 31st October, 7:12am: 29
Update: moved the Mint installation to a subdomain - works fine!
Craig Allen said on Tuesday 17th November, 11:54pm: 30
Hi levi. It was working great. But now I’m getting I’m getting the following error message at the top of my plugins page. Any thoughts on the cause. The publish_that plugin that is mentioned was installed previously without this error occuring.
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /home/public_html/mysite.com/cp/plugins/pi.publish_that.php:451) in /home/public_html/mysite.com/cp/extensions/ext.lg_htaccess_generator_ext.php on line 672
Craig Allen said on Wednesday 18th November, 12:34am: 31
Ignore/delete my last comment Levi. The problem was caused by the publish_that plugin. LG.htaccess Generator was an innocent bystander.
Ben Brunt said on Monday 1st February, 4:15am: 32
I got this working very easily for a few weeks then my site started giving me a ISE 500. This is what i found in the error_log… [Sun Jan 31 08:16:25 2010] [alert] [client 173.162.208.210] /home/47513/domains/benbrunt.com/html/.htaccess: RewriteEngine must be On or Off, referer: http://www.benbrunt.com/
What should i do?
Matt said on Thursday 4th February, 8:43am: 33
Wow…. I spent so long getting this to work, and upon finally achieving success I almost broke down in tears of joy.
A bit excessive I know - but if anyone else is struggling with this then I am happy to try and help.
Craig Allen said on Tuesday 16th March, 5:20pm: 34
I don’t know why, but I’m now having trouble with my stylesheets, whereas it used to work. If I delete the ‘index.php’ from the ‘Name of your site’s index page’ setting in the control panel, it removes the index.php from links such as the following which is generated by the path variable.
But the ‘?’ that then remains in front of ‘css=styles’ kills the link.
Does anyone know a solution?
<link href=”http://www.greeningdarebin.org/index.php?css=styles/.layout.v.1261235075” media=”all” type=”text/css” rel=”stylesheet”>
Craig Allen said on Tuesday 16th March, 6:50pm: 35
Re my last post about getting stylesheets to work:
In in the EE wiki at http://expressionengine.com/wiki/Remove_index.php_From_URLs]this article I found some advice under the section titled ‘Added code to take care of EE CSS under some server setups’. My best guess at interpretting that suggested that I should add the following to my htaccess file.
RewriteCond %{QUERY_STRING} ^(css=.*)$ [NC]
RewriteRule ^(.*)$ /index.php?/%1 [L]
But this doesn’t work.
Dan said on Wednesday 31st March, 12:10pm: 36
Great tool! Just one thing…when I enable it, all works just fine, but I can’t access my control panel anymore unless I go back to my original htaccess file (thank god I made a backup).
Any thoughts as to why?
Thanks!
Dan
Trent said on Tuesday 11th May, 4:08am: 37
Howdy.
Plugin worked great…thanks.
One thing though, I have been pulling my hair out trying to setup the 404 page.
- I am using Structure 1.3.1 (does this make a difference?) and EE v1.6.9
- I go to Global Template Preferences and turn on Strict URL’s and choose a 404 template
Once done EE treats every page I have in structure as a 404.
Are the above steps necessary when using Leevi’s htaccess with the line ErrorDocument 404 /index.php?/{ee:404}
Has anyone successfully got error 404 pages working perfectly whilst removing index.php with http://leevigraham.com/cms-customisation/expressionengine/lg-htaccess-generator/#setting-htaccess-rules and using Structure 1.3.1 for entire site structure?
Any help will be greatly appreciated as I have been at this for hours.
Thanks guys.
Trent
Timo Kuhn said on Tuesday 8th June, 8:48am: 38
What do I need to alter if I have parts of my stite running from a subdomain? (not a subdirectory like in this comment http://newism.com.au/blog/post/39/lg-htaccess-generator-removing-indexphp-from-your-expressionengine-site/#c8368)
Thank you very much.
Carl said on Friday 9th July, 8:17pm: 39
Hi Leevi
We have several domains that we want to 301 to the main .com, for example we have a .co.uk.
We have rewrite rules that do this redirect, but they seem to be clashing with your code. The code we are currently using is:
rewritecond %{http_host} ^mydomain.co.uk [nc]
rewriterule ^(.*)$ http://www.mydomain.com/$1 [r=301,nc]
rewritecond %{http_host} ^www.mydomain.co.uk [nc]
rewriterule ^(.*)$ http://www.mydomain.com/$1 [r=301,nc]
Any ideas?
Thanks
Carl.
Billy said on Saturday 10th July, 3:28am: 40
Carl,
I wonder if it is because you are missing a [L] at the end of the rewriterules?
Also, have you played around with the positioning of your rewrites (i.e. above/below the generated code)?
I would try adding Last to your rules.
Carl said on Saturday 10th July, 3:40am: 41
Billy
Fantastic! Works like a treat.
I looked at the L parameter and discounted it before trying it - DOH!
Just to let others know I have placed my rewrite rules above the rule to remove index.php and works fine.
Thanks again.
Billy said on Saturday 10th July, 3:43am: 42
Carl: No prob! Glad it helped. :)
Cheers,
B
Your comment
Please keep your comments friendly and on topic.