Laravel 5 – Remove Public from URL
Solution 1
For Laravel 5:
- Rename
server.php
in your Laravel root folder toindex.php
- Copy the
.htaccess
file from/public
directory to your Laravel root folder.
That's it!
Solution 2
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
Solution 3
I have solved the issue using 2 answers:
- Renaming the server.php to index.php (no modifications)
- Copy the .htaccess from public folder to root folder (like rimon.ekjon said below)
-
Changing .htaccess it a bit as follows for statics:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1 [L,R=301] RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !^/public/ RewriteRule ^(css|js|images)/(.*)$ public/$1/$2 [L,NC]
If there are any other static files needed just add the extension to the previous declared list
Solution 4
In Laravel 5.5 create .htacess file in your root directory and placed the following code:- Reference Link
<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
</IfModule>
Solution 5
Create .htaccess
file in root directory and place code something like below.
<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
</IfModule>
Related videos on Youtube
user1537360
Updated on March 15, 2022Comments
-
user1537360 over 2 years
I know this is a very popular question but I haven't been able to find a working solution for Laravel 5. I've been trying to migrate from Codeigniter for a long time, but this convoluted installation process keeps putting me off.
I don't want to run a VM, this just seems awkward when switching between projects.
I don't want to set my document root to the public folder, this is also awkward when switching between projects.
I've tried the .htaccess mod_rewrite method
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^(.*)$ public/$1 [L] </IfModule>
This just gives me a Laravel NotFoundHttpException in compiled.php line 7610.
When I tried L4 a while ago, I used the method of moving the contents of the public folder into the root. The structure of L5 is quite different and following the same steps completely broke Laravel (the server would only return a blank page).
Is there a decent method of removing 'public' in a development environment that:
- Works with L5
- Allows me to switch between projects with ease (I'm usually working on 2 or 3 at any one time).
Thanks
** I'm using MAMP and PHP 5.6.2
-
user1537360 over 9 yearsThe folder structure in the guide is different to mine, I imagine he is not using L5? I omitted the changes he made to the Bootstrap/Paths file, because it doesn't exist. The project seems to be working though. Do you think this is ok?
-
kamlesh.bar over 9 yearsmy mistake let me add answer for L5
-
kamlesh.bar over 9 yearsno success trying for same
-
user1537360 over 9 yearsIt seems to work by just modifying the paths in the index.php file, but I'm new to Laravel so obviously can't comment on whether this is stable / safe.
-
Mike Rockétt over 9 yearsThe other folders/files are supposed to be underneath your document root.
-
Kamlesh Kumar over 9 yearsTry this answer on this page : stackoverflow.com/a/28735930/3786343
-
Wasim A. almost 8 yearsThis work for all laravel versions stackoverflow.com/questions/15586397/…
-
Luzan Baral almost 7 yearsThis solution over here worked for me. justcode.me/laravel/…
-
user3151197 over 6 years
-
Snapey over 2 yearsMost of the responses on this page are incredibly bad practice. The ONLY secure solution is to change the document root of your web host to be the public folder. If you are on a server that only publishes the public_html folder, then delete this and create a new public_html symlink that points to and aliases the Laravel public folder.
-
Ali Shahzad over 9 yearsHi, I have tried your method, performed the above steps but it shows the following errors: Warning: require_once(D:\Projects\laravel/public/index.php): failed to open stream: No such file or directory in D:\Projects\laravel\server.php on line 21 Fatal error: require_once(): Failed opening required 'D:\Projects\laravel/public/index.php' (include_path='.;C:\xampp\php\PEAR') in D:\Projects\laravel\server.php on line 21
-
Mr. Tomar over 7 yearsAfter that css not load, bcoz all css are in public and the public is removed from url
-
Muhammad Sadiq over 7 yearsYou can put "public/" before the js or css files while loading, eg Html::script("public/js/....."); --But the best solution would be virtual host...
-
Kabir Hossain over 7 yearsIts ok for everything. but artisan command is not working, just it show "Could not open input file: artisan" . Is there any suggestion ?
-
MasoodRehman over 6 yearsThis method worked, If you are OK to expose your database credentials to users. localhost/laravel/.env
-
Shadman over 6 yearsThis is not a good way to resolve this problem, as you are trying to update in vendors directory which is not good practice.
-
Shadman over 6 yearsyou only need to add
RewriteRule ^(.*)$ public/$1 [L]
in your .htaccess file which you have copied from public directory, by removing this lineRewriteRule ^(.*)/$ /$1 [L,R=301]
-
Brigo over 6 yearsI answered below before reading your answer and this must be the accepted answer. No file changes: just a simple, clever rule.
-
Abhinav Saraswat over 6 years@Raham what is your current url?
-
Deepesh Thapa about 6 yearsJust want to add a short description on top of this gentlemen's work. The above code works on the root public_html folder (I had issues as well). Having said that your core laravel file should be inside public_html folder , i made a mistake that my directory looked like public_html/laravelapp/public if you put the above code inside laravelapp it wont work . Therefore you must copy all your core files into public_html and put the .htaccess file there . Referencing to centOS and Cpanel hosting for laravel.
-
FiliusBonacci about 6 yearsthe best answer! the only one worked in my example, it should have definitely more up votes
-
rahul singh Chauhan almost 6 yearsThanks this is work for me. But I want to know it has any security issue or not.
-
Raham almost 6 years@rahulsinghChauhan my pleasure.Dear I don't know regarding security issue but it ought to be secure.
-
gonzo over 5 yearsWhat does this rule
RewriteRule ^ ^$1 [N
] do? -
Script47 over 5 yearsWhat's the flaws with using this method?
-
Janaka Dombawela over 5 yearsRule number 1: Never edit a core file. Even if it looks easy and nice now, you will pay later.
-
Ferhat KOÇER over 5 years@JanakaDombawela i don't think that way because:
-
Ferhat KOÇER over 5 years@JanakaDombawela I don't think that way because: Senerio 1: If developer a experienced : Open source code is for this job Senerio 2: If developer is a junior, developer must do edit to source code for gain experience
-
Arshad Ameen about 5 yearsThis is the only one worked for me...thank you so much
-
Manisha about 5 yearsAll four ways are good,but i have solved my issue by using first solution.
-
Derk Jan Speelman about 5 years@DeepeshThapa If you want that to work, you simply need to modify the
.htaccess
file so it works with subdirectories. -
Derk Jan Speelman about 5 yearsThis is the only answer here (besides my answer ofcourse) that comes with an easy solution, without any of the downsides the other answers come with, like storage path, assets path and other url/path related issues. And major security flaws for example public access to the
.env
file. -
Luiz Wynne about 5 yearson chained view resources, such as a dashboard with a admin.something.something that doesnt work. Any modification has to be done on the route file?
-
TheLastCodeBender about 5 yearsI really recommend this solution.
-
Samuel Liew about 5 yearsIt's good practice on Stack Overflow to add an explanation as to why your solution should work or is better than the existing solutions. For more information read How To Answer.
-
CodeConnoisseur almost 5 yearsI have this in my .htaccess folder in my root public_html folder but I am still getting /public at the end of my url. ## Redirect to public folder <IfModule mod_rewrite.c> RewriteEngine on RewriteRule ^$ public/ [L] RewriteRule (.*) public/$1 [L] ##SSL Code from STO RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </IfModule> Any ideas?
-
Vincent Decaux almost 5 yearsWorked like a charm for me, I had only cPanel webshost and couldn't change the RootDirectory for Apache. Thanks ! simplest and safest. This will not allow to see your root folder content
-
Haritsinh Gohil almost 5 yearsIt is working fine in production but it is not working in local any suggestion?
-
Derk Jan Speelman almost 5 years@HaritsinhGohil for me it's also working fine in development mode, local server, production server, everywhere
-
Haritsinh Gohil almost 5 yearsi don't know but for me it is not working in local, another solution here has worked in local too, what can be the cause?
-
Derk Jan Speelman almost 5 years@HaritsinhGohil join this room chat.stackoverflow.com/rooms/196804/laravel-and-htaccess to continue our conversation
-
zanderwar almost 5 yearsThis redirects me to /public/public
-
Victor Ejiogu almost 5 years@zanderwar, please what's the Laravel version? Also, I hope you don't have your project on a sub-directory from the main directory?
-
zanderwar almost 5 yearsProject is root, version is 5.6.* - It is on a subdomain though, on shared hosting; unfortunately this cPanel installation forces subdomains to have a folder within public_html
-
Derk Jan Speelman almost 5 years@LuizWynne take a look at my answer
-
eduardo a almost 5 yearsI also recommend this solution
-
Ghanshyam Nakiya almost 5 yearsThis is perfectly working! local and server thank for security help!
-
Shovan almost 5 yearsHello, @DerkJanSpeelman I'm trying to upload my laravel files inside a subfolder in my hosting like: (example.com/projects/laravel/blog) in that case, visitors have to visit example.com/projects/laravel/blog/public, so that I put a .htaccess file with your code in the blog folder root and want it to redirect to the public folder. But it's not working. Here is the Error occurring: The requested URL /public/ was not found on this server. How can i solve this ?
-
Derk Jan Speelman almost 5 years@ShovonDas If you want to make your users go to
example.com/projects/laravel/blog/
. First, create the laravel project inside theblog
folder. ReplaceRewriteCond %{REQUEST_URI} !^/public/
withRewriteCond %{REQUEST_URI} !^/projects/laravel/blog/public/
andRewriteRule ^(.*)$ /public/$1 [L,QSA]
withRewriteRule ^projects/laravel/blog/(.*)$ /projects/laravel/blog/public/$1 [L,QSA]
I think that works. Let me know. TheRewriteRule
works like:RewriteRule pattern target [Flag1,Flag2,Flag3]
Apache RewriteRule documentation -
Varun Ved over 4 yearsThis answer is underrated. Upvoted for Bold and highlighted Don't. It's working absolutely fine.
-
Prappo over 4 yearsThank you so much. This is perfect (y)
-
Manoj Singh over 4 yearsit's working fine, but still .env file accessible directly from URL.
-
Admin over 4 yearsThis is not a perfect answer, rather it is a much unsecure way.
-
Mansour Alnasser over 4 yearsThe Perfect Answer
-
Raham over 4 yearsThank you,@VishalParkash
-
Senior PHP Developer about 4 yearsis it a secure solution?
-
Samik Sengupta almost 4 yearsThis is the correct solution to the problem! Saved me hours.
-
Nhân Trần over 3 yearsthanks a lot, this solution is worked! Why the worked answer not in #2 place
-
mauronet over 3 yearsPlease review other answers creating just .htacess file in your root directory, because this answer can expose sensitive information (like .env file)
-
Abd Abughazaleh over 3 yearsYour site you be available for hackers cos .env file we be viewed for everyone .
-
Raitis Kupce over 3 years@DerkJanSpeelman it works. Though if you type manualy e.g website.com/public/about it shows a valid page in fact two pages are showing the same now. e.g website.com/public/about website.com/about
-
nassim over 3 yearsThis is not secure.
-
Derk Jan Speelman over 3 years@RaitisKupce yeah I'm really out of this game nowadays. I don't do routing via Laravel's
web.php
anymore, I do the routing via the frontend nowadays. vue-router in particular -
Raitis Kupce over 3 years@DerkJanSpeelman do you have any resource where this could be learned? To do specifically this task?
-
Riosant over 3 yearsOMG! Its running too fast, You made it dude.
-
Derk Jan Speelman over 3 years@RaitisKupce and Riosant medium.com/@crocodile2u/…
-
Yohanim over 3 yearsI vote for this answer! Use this answer guys
-
Robin Singh over 3 yearsDo changes in
.htaccess
file instead of copy paste file. -
Chintan Thummar about 3 yearsI have tried many solutions. But this worked like magic for me. This is the highly underrated answer and I am upvoting for this. All who find this answer helpful, please upvote. Thank you @newbdeveloper
-
Pallav Nagar about 3 yearsThanks for the appreciation.
-
Akbarali about 3 yearsThank you very much. The Laravel 8 works very well
-
Qumber almost 3 yearsKeep scrolling for better answer.
-
Abd Abughazaleh almost 3 yearsThis not good , .env will be not secure anymore.
-
Private_GER almost 3 yearsThis is an unbelievably bad answer and probably the number one source of hacked Laravel websites.
-
Loganathan Natarajan almost 3 yearsThis works but I am unable to access any file on the website directly ... like www.test.com/sitemap.xml or www.test.com/images/test.jpg
-
Derk Jan Speelman over 2 years@logudotcom if you want to access certain static files on your website, you need to give access to them. You can do this with htaccess. I strongly suggest to look at the htaccess docs developer.mozilla.org/en-US/docs/Learn/Server-side/…
-
Loganathan Natarajan over 2 years@DerkJanSpeelman Okay, Thanks
-
cdsaenz over 2 yearsBeen looking for months for this solution! The only one that works.. even in subfolders! (Using Laravel 8)
-
cdsaenz over 2 yearsJust wondering how to avoid /public to be recognized too as a valid url..
-
Snapey over 2 yearsThis is incredibly bad advice
-
Snapey over 2 yearsDO NOT DO THIS it is really bad practice
-
Mohammad Salehi about 2 years@AbdAbughazaleh What if you change .env file permission to 600?
-
Steve Moretz about 2 yearsDON'T USE THIS if you are not looking for more problems than you already have.