Making Codeigniter clean URLs cleaner
Usually when working with codeigniter you come across the use case where you need to remove the extra “index” appearing in the URL for purposes ranging from shorter URLs to SEO.
For example,
Current URL style: http://example.com/controller/method/category1/category2/page-name Target URL style: http://example.com/category1/category2/page-name.html
As you can see, the difference in the target URL is the absence of the controller name and the method name and the presence of the extension “.html”. Now, lets see how to achieve this and why the extra extension is required.
Below is my version of .htaccess.
RewriteEngine on
RewriteRule ^([a-z0-9_-]+)\.html$ index.php/page/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|asset|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
The line that is extra is 3 which redirects all the requests for “.html” files to the controller named “page”.
Now, lets look at the page controller which will handle these requests.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Page extends Controller
{
function __construct()
{
parent::Controller();
}
function _remap()
{
$segment_count = $this->uri->total_segments();
$segments = $this->uri->segment_array();
if($segment_count == 0)
{
$this->data['title'] = 'UB Group Wines Division';
$this->load->view('home', $this->data);
}
elseif($segment_count == 2) // Single page
{
$page_url = $segments[2];
// Handle the page request
}
elseif($segment_count == 3) // Page with category
{
$category = $segments[2];
$page_url = $segments[3];
// Handle the category + page request
}
}
}
In this way you can have pages with smaller and cleaner URLs.
Tips:
1. You can use any extension you like. e.g; in case you have static HTML files to server, you can use the extension “.html” for static and “.htm” for non-static files.
2. You can have any number of URL stubs before the “.html” extension and you can access all these stubs in the controller.
Cons:
1. The URL needs an extra extension.
2. Only one controller per extension.
Do let me know what you think about this or if there is any way to improve on this.
Related posts:
- Codeigniter: Separating reads and writes for scaling MySQL Generally websites average a ratio of 9:1 or more for...
Tags: clean url, Codeigniter, codeigniter seo, url rewrite

Why don’t you use the routes.php?
http://codeigniter.com/user_guide/general/routing.html
I’m wondering why you would want the extension (.html, .htm, .php, whatever). If you’re looking for shorter, cleaner URLs, why not:
Current: http://example.com/controller/method/category1/category2/page-name
Target : http://example.com/controller/method/category1/category2
or to really chop it up:
Target : http://example.com/category1/category2
I suppose it makes a difference if your controller/method names are married to your site structure (i.e., http://example.com/products/view/cat1/cat2) or not (http://example.com/whichpage/displayproducts/cat1/cat2) but at least to the way I code, I’m not seeing the benefits of this method.
Cheers,
Bob
@Ruben
Using routes is an option. But in order to get URLs like
http://example.com/category1/category2/page-name
without the controller name and the method name (‘index’ for example); the route would be (Please note that I haven’t tested this below route)
Then you would be able to use any other controller since all the requests are routed to “page” controller.
Do let me know if there is a better routing method I missed.
@Bob
The main reasons I didn’t want
Target : http://example.com/controller/method/category1/category2
is because my URLs would have looked like
http://example.com/page/index/category1/category2
AFAIK, google considers the URL segments to be more important the closer they are to the domain name.
Yes,
Target : http://example.com/category1/category2
is quite possible and using routes at that. However, I think we wouldn’ t be able to use other controllers because of this (Unless we have some filter that checks for the existence of the controller and then the category). Using extensions helps to map a particular extension to a specific controller whithout affecting any other controllers.
One of the main use cases I can think of is for a small blog similar to wordpress.
Hope that makes sense
How about:
Current Url: http://example.com/controller-method/category1/category2
OR
Current Url: http://example.com/subfolder-controller-method/category1/category2
is because my URLs would have looked like
Target Url: http://example.com/index.php/controller/method/category1/category2
OR
Target Url: http://example.com/index.php/controller/method/index/category1/category2
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|asset|robots\.txt)
RewriteRule ^([^/.]+)-([^/.]+)-([^/.]+)/(.*)$ index.php/$1/$2/$3/$4 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|asset|robots\.txt)
RewriteRule ^([^/.]+)-([^/.]+)/(.*)$ index.php/$1/$2/$3 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|asset|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
Using Routes:
$route['^([^/.]+)-([^/.]+)/(.*)'] = "$1/$2/$3";
$route['^([^/.]+)-([^/.]+)-([^/.]+)/(.*)'] = "$1/$2/$3/$4";
I have no idea if that will work as I just wrote it now. Feel free to test it.
Should read:
Target Url: http://example.com/index.php/controller/method/category1/category2
OR
Target Url: http://example.com/index.php/subfolder/controller/method/index/category1/category2
@Henry,
Your code looks good, but my aim is to remove the controller and the method name from the URL.
Target URL style: http://example.com/category1/category2/page-name
Your method is useful to merge the forward slashes in the URL.
Useful code nevertheless, thanks!
Hi, It’s not working for me, I tried to put the .htaccess, index.php is still there. Sorry I’m new to CI.
http://www.domain.com/title/How to 20 cook a rice/2
How to remove the ‘title’ using .htaccess in the link above.
It should be link like this http://www.domain.com/How to 20 cook a rice/2
I am using the codeigniter.
The look like this
$route['title/:any/:num'] = ‘page/title/$1/$2′;
http://www.domain.com/title/How to 20 cook a rice/2
I want to convert this link into
http://www.domain.com/How to 20 cook a rice/2
please help me guys.
How to remove the controller/method for cleaner URL in codeIgniter.
The original url is below
http://www.mydomain.com/controllers/method/variable
and I want my url look like this
http://www.mydomain.com/variable
or http://www.mydomain.com/friendly-url-description/5
5 -> is key or id of the table, and the friendly-url-description is description of the value. please help guys.
Possible to create a Route which only display one slash in the site ?
example: http://example.com/my-articletitle
would be helpful if any of you can give me a little help .
thanks
@Haab : yes it possible.
One problem I notice about CI Urls is how they look inside of google on your website snippet. They all include a ../ inside the URL… have you noticed this and do you have any idea how to remove that ../ it wastes space and is distracting…
Thanks,
Sean
@Sean,
I didn’t really get what you are referring to. You can check the usage of this code snippet on http://www.fourseasonsvineyards.com/
As you can see there are no “../” in the URLs anywhere. Do let me know if I am missing something.
Is there any way to remove only index after controller name.
Now my url is: http://example.com/controller/index/params1/params2
But target is : http://example.com/controller/params1/params2
Please reply the solution