105

I need to remove index.php or public/index.php from the generated URL in Laravel; commonly path is localhost/public/index.php/someWordForRoute, It should be something like localhost/someWordForRoute.

.htaccess

<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>

RewriteEngine On

# Redirect Trailing Slashes.
RewriteRule ^(.*)/$ /$1 [L,R=301]

# Handle Front Controller.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php[L]

app/config/app.php

'url' => 'http://localhost',

How can I change that?

TuGordoBello
  • 4,350
  • 9
  • 52
  • 78
  • 7
    [Pretty URLs in Laravel](http://laravel.com/docs/installation#pretty-urls). Make sure `mod_rewrite` is enabled. – Kryten May 23 '14 at 20:36
  • 1
    http://stackoverflow.com/questions/21662378/routes-not-working-without-index-php/21662885#21662885 – The Alpha May 23 '14 at 20:39
  • @Kryten doesnt work =/ – TuGordoBello May 26 '14 at 19:13
  • Is your document root pointing at the intended folder, i.e `/var/www/project_name/public` – Kiee Oct 25 '14 at 10:48
  • 2
    This is the solution when the other solution doen't work http://www.dev-metal.com/enable-mod_rewrite-ubuntu-14-04-lts/ – TuGordoBello May 28 '14 at 19:38
  • or you could try moving the files too like this: https://youtu.be/ybJYyU5FPv4 – MD Singh Nov 29 '15 at 05:25
  • In Laravel, you need not to remove index.php. It will be automatically removed for you. Just make public folder as the document root. – Ankit Vishwakarma Jul 25 '18 at 19:40
  • 1
    Reopen voter: this question is fundamentally misguided, and stems from a misconfiguration of the web server. The only correct solution is to set the document root of the web server to the public directory. All the highest-voted answers here create potential security problems and encourage bad practices, which is why I've marked it as duplicate of a question whose top answer is the correct one. – miken32 Jun 14 '23 at 17:28

19 Answers19

152

Option 1: Use .htaccess

If it isn't already there, create an .htaccess file in the Laravel root directory. Create a .htaccess file your Laravel root directory if it does not exists already. (Normally it is under your public_html folder)

Edit the .htaccess file so that it contains the following code:

<IfModule mod_rewrite.c>
   RewriteEngine On 
   RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

Now you should be able to access the website without the "/public/index.php/" part.

Option 2 : Move things in the '/public' directory to the root directory

Make a new folder in your root directory and move all the files and folder except public folder. You can call it anything you want. I'll use "laravel_code".

Next, move everything out of the public directory and into the root folder. It should result in something somewhat similar to this: enter image description here

After that, all we have to do is edit the locations in the laravel_code/bootstrap/paths.php file and the index.php file.

In laravel_code/bootstrap/paths.php find the following line of code:

'app' => __DIR__.'/../app',
'public' => __DIR__.'/../public',

And change them to:

'app' => __DIR__.'/../app',
'public' => __DIR__.'/../../',

In index.php, find these lines:

require __DIR__.'/../bootstrap/autoload.php';     
$app = require_once __DIR__.'/../bootstrap/start.php';

And change them to:

require __DIR__.'/laravel_code/bootstrap/autoload.php';     
$app = require_once __DIR__.'/laravel_code/bootstrap/start.php';

Source: How to remove /public/ from URL in Laravel

Luzan Baral
  • 3,678
  • 5
  • 37
  • 68
  • 7
    If you use Debian Linux, don't forget to edit `etc/apache2/apache2.conf` changing from `AllowOverride None` to `AllowOverride All` where you see the Directory config, `` . – Robin Hood Jan 20 '15 at 15:21
  • 1
    I had only to had the .htaccess file to my root directory to get it working. – Mário Rodrigues Feb 04 '15 at 11:20
  • 12
    Moving to /root isn't a good advice at all in production mode! There's a reason why the public folder exists – toesslab Apr 04 '15 at 07:44
  • To ensure the rewrite rules work check that the apache config ` Options Indexes FollowSymLinks MultiViews **AllowOverride All** ` – Japheth Ongeri - inkalimeva May 20 '15 at 18:04
  • What if I have no conf access on hosting? – Peter Mar 30 '16 at 08:45
  • @Daenu What is purpose of public folder what problem will removing it will cause on production? – Always_a_learner May 19 '16 at 12:31
  • 1
    Hell no. Never ever do that. – Daniel Steiner May 30 '16 at 14:11
  • Along with above.htaccess code rename our server.php file from root to index.php. These both combinations worked for me. !! thank @Luzan. – Alankar More Aug 25 '16 at 10:27
  • @Luzan Baral I tried this but not working for me. Why not working in my Case. Created `5.2` Project as `BondOnFire`, giving the read write permissions to `Storage` folder, the welcome screen comes. Thn I run `php artisan make:auth`, it works. I create a Folder `Bond` in `BondOnFire` and put all the code in it except public folder. I take out all the code of public folder outside it in BondOnFire directory . Then changed the .htaccess file and restarted serve.when I click on "Register" on the right side of the home screen, it says requested URL not found. Can you please help, what am I missing. – Mukesh Joshi Aug 26 '16 at 06:48
43

I tried this on Laravel 4.2

Rename the server.php in the your Laravel root folder to index.php and copy the .htaccess file from /public directory to your Laravel root folder.

I hope it works

Tejas Jadhav
  • 693
  • 2
  • 10
  • 11
  • 2
    If the accepted answer by Luazan doesn't work then this will suffice. Although I would make sure to edit the index.php file in the public folder to redirect users out of public if they go straight to that link. – Brad Bird Mar 07 '15 at 09:21
  • 4
    The js and css files are not loaded anymore from public folder – llioor Aug 20 '15 at 22:27
  • @MaHDyfo - why its not secure ? and how ? – 151291 Jun 15 '18 at 17:31
  • 2
    @151291 because .env file ia accessible for everyone visits your site this way. unless you secure your webserver to avoid this. – Mahdyfo Jun 18 '18 at 16:34
21

Don't get confused with other option the snippet below I am using and will be useful for you too. Put the below htacces in your root.

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule    ^$    public/    [L]
    RewriteRule    (.*) public/$1    [L]
</IfModule>

Go to your public directory and put another htaccess file with the code snippet below

<IfModule mod_rewrite.c>
    RewriteEngine On
    # Removes index.php from ExpressionEngine URLs  
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?url=$1 [PT,L]

</IfModule>

Its working... !!!

Laravel Uses below .htaccess

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
Ankit Vishwakarma
  • 1,573
  • 16
  • 13
15

1) Check whether mod_rewrite is enabled. Go to /etc/apache2/mods-enabled directory and see whether the rewrite.load is available. If not, enable it using the command sudo a2enmod rewrite.It will enable the rewrite module. If its already enabled, it will show the message Module rewrite already enabled.
2)Create a virtual host for public directory so that instead of giving http://localhost/public/index.php we will be able to use like that http://example.com/index.php. [hence public folder name will be hidded]
3)Then create a .htaccess which will hide the index.php from your url which shoul be inside the root directory (public folder)

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
Orchid
  • 572
  • 4
  • 17
13

HERE ARE SIMPLE STEPS TO REMOVE PUBLIC IN URL (Laravel 5)

1: Copy all files form public folder and past them in laravel root folder

2: Open index.php and change

From

 require __DIR__.'/../bootstrap/autoload.php';

To

 require __DIR__.'/bootstrap/autoload.php';

And

$app = require_once __DIR__.'/../bootstrap/app.php';

To

$app = require_once __DIR__.'/bootstrap/app.php';

In laravel 4 path 2 is $app = require_once __DIR__.'/bootstrap/start.php'; instead of $app = require_once __DIR__.'/bootstrap/app.php';/app.php

That is it.

Khandad Niazi
  • 2,326
  • 3
  • 25
  • 22
7

For Laravel 4 & 5:

  1. Rename server.php in your Laravel root folder to index.php
  2. Copy the .htaccess file from /public directory to your Laravel root folder.

That's it !! :)

Udhav Sarvaiya
  • 9,380
  • 13
  • 53
  • 64
Abhijeet Navgire
  • 683
  • 7
  • 20
5

This likely has very little to do with Laravel and everything to do with your Apache configs.

Do you have access to your Apache server config? If so, check this out, from the docs:

In general, you should only use .htaccess files when you don't have access to the main server configuration file. There is, for example, a common misconception that user authentication should always be done in .htaccess files, and, in more recent years, another misconception that mod_rewrite directives must go in .htaccess files. This is simply not the case. You can put user authentication configurations in the main server configuration, and this is, in fact, the preferred way to do things. Likewise, mod_rewrite directives work better, in many respects, in the main server configuration.

... In general, use of .htaccess files should be avoided when possible. Any configuration that you would consider putting in a .htaccess file, can just as effectively be made in a section in your main server configuration file.

Source: Apache documentation.

The reason why I mention this first is because it is best to get rid of .htaccess completely if you can,and use a Directory tag inside a VirtualHost tag. That being said, the rest of this is going to assume you are sticking with the .htaccess route for whatever reason.

To break this down, a couple things could be happening:

  1. I note, perhaps pointlessly, that your file is named .htacces in your question. My guess is that it is a typo but on the off chance you overlooked it and it is in fact just missing the second s, this is exactly the sort of minor error that would leave me banging my head against the wall looking for something more challenging.

  2. Your server could not be allowing .htaccess. To check this, go to your Apache configuration file. In modern Apache builds this is usually not in one config file so make sure you're using the one that points to your app, wherever it exists. Change

    AllowOverride none
    

    to

    AllowOverride all
    

    As a followup, the Apache documents also recommend that, for security purposes, you don't do this for every folder if you are going to go for .htaccess for rewriting. Instead, do it for the folders you need to add .htaccess to.

  3. Do you have mod_rewrite enabled? That could be causing the issues. I notice you have the tag at the top <IfModule mod_rewrite.c>. Try commenting out those tags and restart Apache. If you get an error then it is probably because you need to enable mod_rewrite: How to enable mod_rewrite for Apache 2.2

Hope this helps. I've named some of the most common issues but there are several others that could be more mundane or unique. Another suggestion on a dev server? Re-install Apache. If possible, do so from a different source with a good tutorial.

Community
  • 1
  • 1
smcjones
  • 5,490
  • 1
  • 23
  • 39
5

Also make sure the Rewrite Engline is turned on after editing the .htaccess file

sudo a2enmod rewrite
Rafik Bari
  • 4,867
  • 18
  • 73
  • 123
  • Good observation I was on a new server and actually had to enable it (and add the necessary bits in the apache configuration as well) using this https://www.digitalocean.com/community/tutorials/how-to-rewrite-urls-with-mod-rewrite-for-apache-on-debian-9 – cdsaenz Oct 11 '20 at 02:48
2

You have to perform following steps to do this, which are as follows

  • Map your domain upto public folder of your project (i.e. /var/www/html/yourproject/public) (if using linux)

  • Go to your public folder edit your .htaccess file there

AddHandler application/x-httpd-php72 .php
<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect non-www to www
    RewriteCond %{HTTP_HOST} !^www\.
    RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    # Redirect non-http to https
    RewriteCond %{HTTPS} off
    RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

    # Remove index.php
    RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
    RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
</IfModule>


  • The last three rules are for if you are directly accessing any route without https, it protect that.
Shahrukh Anwar
  • 2,544
  • 1
  • 24
  • 24
2

create a new file with the name of .htaccess and add below lines will fix it.

<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
    Options -MultiViews
</IfModule>

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ ^$1 [N]

RewriteCond %{REQUEST_URI} (\.\w+$) [NC]
RewriteRule ^(.*)$ public/$1 

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ server.php

I am sure it will be fixed, as I faced this issue multiple times and fixed this way.

Thank You.

Imad Ullah
  • 929
  • 9
  • 17
0

Laravel ships with a pretty URL .htaccess already... you should be good to go out of the box... http://laravel.com/docs/installation#pretty-urls

Make sure mod_rewrite is enabled and that your home path is set to the public directory of your application.

Kisuka
  • 1,832
  • 1
  • 15
  • 10
0
 RewriteEngine on

 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d

 RewriteRule ^(.*)$ index.php/$1 [L]

use this in .htaccess and restart the server

Arun
  • 1
0

Hope this helps like it did for me.

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
Harry Bosh
  • 3,611
  • 2
  • 36
  • 34
0

Rename the server.php in the your Laravel root folder to index.php and copy the .htaccess file from /public directory to your Laravel root folder.

Udhav Sarvaiya
  • 9,380
  • 13
  • 53
  • 64
Rizwan Taj
  • 15
  • 1
  • 9
0

I just installed Laravel 5 for a project and there is a file in the root called server.php.

Change it to index.php and it works or type in terminal:

$cp server.php index.php
Barry
  • 3,303
  • 7
  • 23
  • 42
0

If you use IIS Windows Server add web.config file in root folder and put the below code :

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Imported Rule 1" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{URL}" pattern="^system.*" ignoreCase="false" />
                    </conditions>
                    <action type="Rewrite" url="/index.php/{R:1}" />
                </rule>
                <rule name="Imported Rule 2" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                        <add input="{R:1}" pattern="^(index\.php|images|robots\.txt|css)" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="index.php/{R:1}" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

and if you use .htaccess use this one :

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Abd Abughazaleh
  • 4,615
  • 3
  • 44
  • 53
0

PLEASE NOTE

when serving a Laravel project with Docker: you won't need to do any of this. Only use this option when your root (or more commonly: public_html) directory of your website is your Laravel project (this is not the case when you're using Docker).

DON'T!

YOU REALLY SHOULD NOT rename server.php in your Laravel root folder to index.php and copy the .htaccess file from the /public directory to your Laravel root folder!!!

This way everyone can access some of your files (.env for example). Try it yourself. You don't want that!

DO

Instead, you should create an .htaccess file in your root like this:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ /public/$1 [L,QSA]

This will silently rewrite all your base URIs to the /public folder. Even all Headers, for example the HTTP Authorization Header, and all optional URI parameters will silently be passed on to the /public folder as well.

That's all

Imran Vora
  • 47
  • 1
  • 3
0

Nginx configuration, you can use the following equivalent configuration

location / {
if (!-e $request_filename) {
    rewrite ^(.*)$ /public/$1 last;
}

}

xpredo
  • 1,282
  • 17
  • 27
-3
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)/(public)/(index.php)/$ $1/$4 [L]
</IfModule>
Heidar Ammarloo
  • 421
  • 2
  • 11