Minimize your URLs in Codeigniter

Don’t wait until your customer or … your browser(!) start to mention that your URL is way to big from the usually title.

Well the first thing that you realize when you install Codeigntier is that the URLs are really huge, not SEO friendly and not user friendly.

Let’s try to minimize as much as we can for your dynamic created URLs. Below we will explain and give solutions to minimize the URLs as much as possible with htaccess, some route tricks and the _remap() method of Codeigniter.

1. Removing the index.php

Let’s start with our big URL:

http://mycustomproject.com/index.php/webpages/view/my-url-title-of-the-post

The first thing that you usually do for your Codeigniter project is to remove the index.php file from the URL. To do it so, it’s really easy:

1st step

Add this code to your .htaccess file to your root of your project.

<IfModule mod_rewrite.c>
# Turn on URL rewriting
RewriteEngine On

# If your website begins from a folder e.g localhost/my_project then
# you have to change it to: RewriteBase /my_project/
# If your site begins from the root e.g. example.local/ then
# let it as it is
RewriteBase /

# Protect application and system files from being viewed when the index.php is missing
RewriteCond $1 ^(application|system|private|logs)

# Rewrite to index.php/access_denied/URL
RewriteRule ^(.*)$ index.php/access_denied/$1 [PT,L]

# Allow these directories and files to be displayed directly:
RewriteCond $1 ^(index\.php|robots\.txt|favicon\.ico|public|assets|css|js|images)

# No rewriting
RewriteRule ^(.*)$ - [PT,L]

# Rewrite to index.php/URL
RewriteRule ^(.*)$ index.php/$1 [PT,L]
</IfModule>

After the creation of the .htaccess file your project structure will have to look like this:

website_folder/
–––– application/
–––– assets/
–––– system/
–––– user_guide/
---- .htaccess <-------------------------
–––– index.php
–––– license.txt

2nd step

Now go to : application/config/config.php and change the:

$config['index_page'] = 'index.php';

to

$config['index_page'] = '';

So now your URL will look like this:

http://mycustomproject.com/webpages/view/my-url-title-of-the-post

Note 1: If you are running in your local machine and your don't have configured the virtual host for example to be :
http://mycustomproject.com/webpages/view/my-url-title-of-the-post
but your URLs looks more than this:
http://localhost/website_folder/webpages/view/my-url-title-of-the-post

don't forget to change your RewriteBase from:

RewriteBase /

to

RewriteBase /mycustomproject/

or something similar it depends of where your Codeigniter project starts.

Note 2: In some cases perhaps you will realize that your .htaccess simply doesn't work and all the webpages URLs show the index webpage. If this happens to you then go to application/config/config.php and change the:

$config['uri_protocol'] = 'AUTO';

to:

$config['uri_protocol'] = 'PATH_INFO';

or:

$config['uri_protocol'] = 'REQUEST_URI';

it depends of your server's configuration. To try it just change it and see if the URL works for you correctly

Note 3: If you prefer to add a less secure .htaccess for your project, much more minimal and you don't want to write each time the exceptions of the files that you don't want to included them to the rules, you can simply use this code:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

This is the most common .htaccess (it is also used from the default installation of WordPress) thought it is not suggested as you don't protect your folders if the index.php is missing or a new file/folder is added to your project without knowing it.

2. Removing 1st URL segment

So now that we removed the annoying index.php from URL let's minimize our URLs with the routes.

Our basic example that we will work with is the below:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Webpages extends CI_Controller {

	function __construct()
	{
		parent::__construct();
	}

	function index()
	{

	}

	function about()
	{

	}

	function blog($url_title = '')
	{

	}

	function view($url_title = '')
	{

	}

}

To remove our first segment we have to choose which our base Controller will be. In our case we will choose that Webpages will be our basic Controller. The Controllers Admin and Forums will be our secondary let's say Controllers

There are two ways to minimize your URLs:

  • Routing by hand
  • Routing automatically (I always prefer this one)

Routing by hand

So let's see how we can can minimize our URLs by hand. This means that everytime we add or edit a function at our Controller we have to go to : application/config/routes.php
and change the routes in each case. So let's have an example of our basic controller:

Go to application/config/routes.php and add something like this:

$route['default_controller'] = 'webpages'; //Our default Controller

//Get rid of the first segment (in our case we get rid of webpages)
$route["about"] = 'webpages/about';
$route["blog/(.*)"] = 'webpages/blog/$1';
$route["view/(.*)"] = 'webpages/view/$1';

So now with this simple code we have get rid of the first controller name from our basic webpages.

Routing automatically

Many of you probably already know it but it is really boring to create the routes every time by hand. So that's why I created an automatically routing that actually removes the controller of your default controller. The below code is written to handle all the scenarions. Simple URLs and multilingual URLs. Let's go and take a look of our routes how it will look like.

If you don't have a multilingual website the routes are easy. You can simply copy the below code to application/config/routes.php:

$default_controller = "webpages";
$controller_exceptions = array('admin','forums');

$route['default_controller'] = $default_controller;
$route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/$1';
$route['404_override'] = '';

If you are having a multilingual website, it is a bit more complicated as you have lot of scenarios to cover. However don't worry about it as you can simply copy the below lines of code to application/config/routes.php:

$default_controller = "webpages";
$language_alias = array('gr','fr');
$controller_exceptions = array('admin','forums');

$route['default_controller'] = $default_controller;
$route["^(".implode('|', $language_alias).")/(".implode('|', $controller_exceptions).")(.*)"] = '$2';
$route["^(".implode('|', $language_alias).")?/(.*)"] = $default_controller.'/$2';
$route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/$1';
foreach($language_alias as $language)
	$route[$language] = $default_controller.'/index';
$route['404_override'] = '';

So let me explain how it works.

The only thing that you will actually care to change is the first three lines of code:

$default_controller = "webpages";
$language_alias = array('gr','fr');
$controller_exceptions = array('admin','forums');

As it is the only one that you actually need to change. So how it works? It's really easy.
You add your default controller to your variable $default_contoller.

The $language_alias is the language element that you want to add if you have a multilingual website for example:

http://mycustomproject.com/blog
http://mycustomproject.com/gr/blog
http://mycustomproject.com/fr/blog

And of course the http://mycustomproject.com/gr and http://mycustomproject.com/fr are routing to the index of your basic Controller.

The $controller_exceptions are the controllers that will NOT follow this routing structure. For example:

http://mycustomproject.com/admin/
http://mycustomproject.com/forums/

So you can easily use the controller with name Admin and controller with name Forums with the same way as you used it before.

Now we removed our first segment so our dynamic URLs will look like this:

  • http://mycustomproject.com/about
  • http://mycustomproject.com/view/my-url-title-of-the-post
  • http://mycustomproject.com/blog/url-title-of-post

3. Removing 2nd URL segment

One way to do it is by using the _remap() method of Codeigniter. For more go to Controllers User Guide and search for the _remap() method. Let's have an example of how to use it:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Webpages extends CI_Controller {

	function __construct()
	{
		parent::__construct();
	}

function _remap()
{
	$segment_1 = $this->uri->segment(1);

	switch ($segment_1) {
		case null:
		case false:
		case '':
			$this->index();
		break;

		case 'about':
			$this->about();
		break;

		case 'blog':
			$this->blog($this->uri->segment(2));
		break;

	default:
		//This is just an example to show
		//the 404 page if the page doesn't exist
		$this->db->where('url_title',$segment_1);
		$db_result = $this->db->get('webpages');

		if($db_result->num_rows() == 1)
		{
			$this->view($segment_1);
		}
		else
		{
			show_404();
		}
	break;
	}
}

	function index()
	{

	}

	function about()
	{

	}

	function blog($url_title = '')
	{

	}

	function view($url_title = '')
	{

	}

}

So when you are using the _remap function of Codeigniter you have to decide which method will use every time. The good part is that you will have full control of what to do with each method. However it can take lot of time if you have many functions in your controller. So now your URLs will look like this:

  • http://mycustomproject.com/my-url-title
  • http://mycustomproject.com/about
  • http://mycustomproject.com/blog/url-title-of-post

 

Are you done with reading? Well you can now download the files that we used at this post or you can view the files from github

← Previous post

Next post →

67 Comments

  1. Super!
    Thx
    How about short links in Laravel?

  2. very nice
    gonna try it
    thank you


  3. case ‘about’:
    $this->search(); // <= it is correct?

  4. Muhammad Owais Akbar

    very nice article i need this today i will implement this Inshallah

  5. Ram krishna dhakad

    This is working for me.Thank You.

  6. Satnam Singh

    Really Awesome !!! Thanks !!!!!!

  7. Jean-Pierre

    OMFG this saved me sooo much time && grief. Way to be thorough by the by. You sir are a gentleman and a scholar.

  8. thank you for ur tutorial, very helpfull

  9. jawwad ahmed

    sooooooooooooper

  10. great post, helped me alot

  11. Thanks it work, but my css doesnt running.. if i put .htaccses how i write my css
    this my code
    <link rel="stylesheet" href="css/style.css” type=”text/css” media=”screen” />

    • web_and_development

      You can add your folders at the:

      # Allow these directories and files to be displayed directly:
      RewriteCond $1 ^(index.php|robots.txt|opensearch.xml|favicon.ico|assets|forums)

      for example in your case you can have:

      # Allow these directories and files to be displayed directly:
      RewriteCond $1 ^(index.php|css|js|images|robots.txt|opensearch.xml|favicon.ico|assets|forums)

    • thank!

  12. hi. Thank for post

    It work with me. But i have a little problem.

    My structure folder:

    root

    — application

    — system

    — public

    ——css

    ———-style.css

    When i change like u. My website find path of the css file.

    please help me.

    sorry, my english is bad

    • In the view. i config path of the css:

      <link rel="stylesheet" href="/public/default/css/style.css” type=”text/css” />

      • sorry. My website can not find path of the css file

    • web_and_development

      Guys it is pretty clear that you can add as many folders you like as an exception. For example in your case you will have:

      # Allow these directories and files to be displayed directly:
      RewriteCond $1 ^(index.php|robots.txt|opensearch.xml|favicon.ico|css|js|images|public)

      So for example if at the future you want to add the folder let’s say “forums” you can do it like this:

      # Allow these directories and files to be displayed directly:
      RewriteCond $1 ^(index.php|robots.txt|opensearch.xml|favicon.ico|css|js|images|public|forums)

      and so on…

  13. prabukarana

    hey bro, when i upload website. i have problem, website will be 404 not found.

    example helloworld.com, how should i write my RewriteBase / … ?

    • web_and_development

      Can you please be more specific? What did you try? Did you try to remove the .htaccess to see if this is causing the 404 not found? Moreover is your website with this structure? localhost/helloworld . If yes you have to change the RewriteBase / to RewriteBase /helloworld

      • prabukarana

        i’ve been solved that…
        i wrote this in my web directory in server..

        RewriteEngine On
        RewriteBase /
        RewriteRule ^index.php$ – [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php [L]

        blank my rewritebase.. and it work, btw thx bro…

      • akhunzada

        i do all the steps as you mention but

        Not Found

        The requested URL /codeIgniter/welcome/khan was not found on this server.

        display this message

        • web_and_development

          Hello there, can you try “RewriteBase /codeigniter/”

  14. rdiksa

    hay, i can remove the annoying index.php . i’ve followed your tutorial step by step. does any version of XAMPP efects your method?

  15. pujiew

    thanks, good post

  16. Can you explain me how can I redirect from web pages Controller to admin Controller? redirect(admin/home); didn’t work for me

    Tanks!

  17. thanks for this post. it’s a great post and is quite helpful.

  18. Costin Beiu

    Nice one! I have a a problem with this re routing. Instead of my_site.com/index.php/admin/admin (css works), I set to my_site.com/admin but the css doesn’t work anymore. The css is in application/css/style.css. I tried ../application/css/style.css and /application/css/style.css, but still not working. Any advice?

    • web_and_development

      Hello Costin,

      You need to actually move your css outside the application folder. The application folder is a good practice to not be accessible from the web. This way you prevent hacking. Try to move the css folder outside the application folder and then try mysite.com/css/style.com

  19. Thanks, this is what i needed to remove the pesky default controller name!

  20. Silencer

    Hi, without my .htaccess file website already routes pages. However, since there is no folder with that name i get the error not found. In my config file index.php is deleted and im working on local. Note that I downloaded website from live server and it’s working properly there. When I delete inside of the .htaccess or .htaccess nothing is changed. Let’s say I’m trying to route that page “website_name”/about and I’m already routing but I get that not found error. However, when I change the link on browser like “website_name/index.php/about” it opens without problems. But when I click on “About” on website it goes to “website_name/about” and couldn’t found the page. Since live version is without index.php, I’m trying to opening it up but it seems whatever I do just doesn’t working. If you could help me that would be great. Thanks!

  21. armstrong

    hi thnks for ur guide with this redirect my images are not displaying which are in images folders

  22. Sara Abdalaziz

    how to route someting like this to get ride of function and .jpg
    http://localhost/ci_alcwea/produacts/get_prodact/antic_Coil.jpg

  23. Great Posts. Helped me a lot.

    Have you article about multiple 404 Pages ?

    I have 2 section, frontpage and admin page, if visitor type wrong URL, I want to redirect to 404 front’s page, and if I in administrator section, when I type wrong URL, it must redirect to 404 admin’s page.

    can it handled by routing like these ?

    Thanks

  24. Excellent write up, deserve a spicy biryani!

    • web_and_development

      Thank you very much. However, I don’t like spicy foods 🙂

  25. suraj waghmare

    really helpful dear

  26. Perfect Example. Thanks

  27. xubayerpantho

    hellow bro i can’t remove my 1st url segment from my default controller. I am using CI version 2.1.4 Plz help, if you want i can send my code in your mail.

  28. Nagu Yallu

    i did same as above but its not working for me Please any body help me

  29. not working at my side

    $route[‘default_controller’] = “welcome”;

    $route[“about”] = ‘welcome/contactus’;

    $route[“content/(.*)”] = ‘webpages/content/$1’;

    $route[‘404_override’] = ”;

  30. bakoscsaba

    thanks

  31. kendra

    I have a question. what is (gr&fr) AND (admin&forum) there? what is the function? looking forward to your response 🙂

  32. Sanjay

    Is this applicable only for one controller? I want to do this type route for all my rest controller. Suggest me the d way to do it for all other controller too. thanks in advance.

  33. thanks for the file, it’s really save my day

  34. Sam KaNghoshi Naholo

    Thank you.

  35. same page is opening if i add the unwanted text after Slash for example
    In this Page http://www.example/kb/article/mac-data/
    or in this Page http://www.example/kb/article/mac-data/72riwgffffg

    in codeigniter

  36. Sharma Aunj

    same page is opening if i add the unwanted text after Slash for example
    In this Page http://www.example/kb/article/mac-data/
    or in this Page http://www.example/kb/article/mac-data/72riwgffffg

    in codeigniter

  37. Avinash

    this code is note working

  38. Alpheus Tech

    Thank you for this awesome snippet. All worked until I decided to pass other segments.
    Works: http://site.tld/_remap/uri_segment
    Not working: http://site.tld/_remap/userid/1/email/user@site.tld

    My route

    $default_controller = “directory/controller/method”;
    $controller_exceptions = array(‘test’, ‘test2’);
    $route[‘directory/controller/method’] = $default_controller;

  39. Max Joe

    Nice Post , I will also refer following for removing index.php from codeigniter.
    http://tutsway.com/remove-index.php-from-url-in-codeigniter.php

  40. i’m trying to remove auth from url but those url still exist, i used this code, where is wrong

    $default_controller = “auth”;
    $controller_exceptions = array(‘admin’,’member’);
    $route[‘default_controller’] = $default_controller;
    $route[“^((?!b”.implode(‘b|b’, $controller_exceptions).”b).*)$”] = $default_controller.’/$1′;
    $route[‘404_override’] = ”;

  41. Awesome! Just saved my life.

  42. Haroon @WebSight

    $default_controller = “admin”;

    $controller_exceptions = array(‘auth’,’user’);

    $route[‘default_controller’] = $default_controller;

    $route[“^((?!b”.implode(‘b|b’, $controller_exceptions).”b).*)$”] = $default_controller.’/$1′;

    $route[‘404_override’] = ”;

    from admin controller which is default .i called a method but my view is not loading.

  43. กีรติพร ลีลาวันทนพันธุ์

    Thank You Very much

  44. I did the same as told, the index.php is removed from the url but the pages is not opening its showing object not found,

    means the default controller is opening, but when i jumping to another controller its showing object not found

  45. thanks this turtorial its very great..

  46. Mahesh Sharma

    It was really helpful. Thank you.

  47. what if i define base url and including index.php ?

  48. Thanks it’s help me !