Laravel on a sub domain or folder: Remove public from URL

by Remy Pereira on 20th September 2016

Laravel creates a folder named public inside your Laravel Application Folder and the default path to your application is <Laravel Folder>/public. So the resulting URL would be something like http://www.domain.com/public/. After you complete Laravel Installation, you have to set your Apache DocumentRoot to the public folder inside your Laravel Folder. On Apache you can do this by editing httpd.conf. This would remove the /public from the URL and also make rest of the content of Laravel Application Folder, other than the public folder, inaccessible.

But if for some reason you are not allowed to change Document Root or if you dont have access to httpd.conf then you can still do this by overriding the settings using .htaccess file.

This article shows you how to install Laravel in a subfolder inside your DocumentRoot, which is normally the case if you are hosting the Laravel project in a subdomain,for example http://www.domain.com/blog.

Method 1 : Using .htaccess

If you are installing Laravel in a sub-folder(blog) inside your Document Root(Apache Root Folder\htdocs). After installation the directory structure of Apache Root Folder\htdocs\blog looks like this:

htdocs
  |
  |-- blog
	 |-- app 	<DIR> 
	 |-- bootstrap  <DIR>
	 |-- config 	<DIR>   
	 |-- database 	<DIR>          
	 |-- public 	<DIR>          
	 |-- resources 	<DIR>          
	 |-- routes 	<DIR>          
	 |-- storage 	<DIR>           
	 |-- tests 	<DIR>          
	 |-- vendor 	<DIR>          
	 |-- .env
	 |-- .env.example
	 |-- .gitattributes
	 |-- .gitignore
	 |-- artisan
	 |-- composer.json
	 |-- composer.lock
	 |-- gulpfile.js
	 |-- package.json
	 |-- phpunit.xml
	 |-- readme.md
	 |-- server.php

If your URL is http://www.domain.com, Laravel application is now accessible at http://www.domain.com/blog/public/

To remove public from the URL and make it just http://www.domain.com/blog/

Create a .htaccess file at this location with the following lines:


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

This redirects all requests for /blog/ to /blog/public/

Also edit routes/web.php and add the following lines:


Route::get('/blog/', function () {
    return view('welcome');
});

Now you can access your Laravel Application at http://www.domain.com/blog/

Note: Without the web.php edit, if you try to access the url http://www.domain.com/blog you will get a NotFoundHttpException

Method 2: Moving the files and setting paths in index.php

Create the Laravel Project outside your Document Root named blog_app (you can give any name you like). Once the installation is finished, move the public folder to Document Root. Rename the public folder to the name you would like to appear in the URL, say blog.

Lets say your Laravel installation is in <Apache Root Folder>/blog_app/ and your Document root is <Apache Root Folder>/htdocs. Now you move the <Apache Root Folder>/blog_app/public folder to <Apache Root Folder>/htdocs/blog

Then go to htdocs/blog and open index.php
Find the following 2 lines:


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

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

The paths are defined relative to current directory, i.e, one level up (../) from current location. In our case these are located two levels up, (../../). Change the paths as follows:


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

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

Now you can access your Application at http://www.domain.com/blog/

Of the two methods, the second method is more secure and preferred, because all your project files (Models, Views, Controllers, Environment Config) are isolated from Document Root and hence they are protected from unauthorized access.


Post a comment

Comments

Ahaan | August 30, 2022 2:19 PM |

Found Userful

ardi ardiyansyah | November 12, 2020 1:13 PM |

your code have a typo sir, require __DIR__.'/../../bloc/bootstrap/autoload.php'; $app = require_once __DIR__.'/../../blog/bootstrap/app.php'; and it doesn't work afterall. first if your project named "blog_app", then you should make index.php from public like this require __DIR__.'/blog_app/vendor/autoload.php'; $app = require_once __DIR__.'/blog_app/bootstrap/app.php';

Gaurang Ghinaiya | April 24, 2017 7:49 AM |

i use method 1 still getting 'NotFoundHttpException'