Laravel 5 – Remove Public from URL

325,212

Solution 1

For Laravel 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!

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:

  1. Renaming the server.php to index.php (no modifications)
  2. Copy the .htaccess from public folder to root folder (like rimon.ekjon said below)
  3. 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>
Share:
325,212

Related videos on Youtube

user1537360
Author by

user1537360

Updated on March 15, 2022

Comments

  • user1537360
    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:

    1. Works with L5
    2. 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
      user1537360 over 9 years
      The 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
      kamlesh.bar over 9 years
      my mistake let me add answer for L5
    • kamlesh.bar
      kamlesh.bar over 9 years
      no success trying for same
    • user1537360
      user1537360 over 9 years
      It 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
      Mike Rockétt over 9 years
      The other folders/files are supposed to be underneath your document root.
    • Kamlesh Kumar
      Kamlesh Kumar over 9 years
      Try this answer on this page : stackoverflow.com/a/28735930/3786343
    • Wasim A.
      Wasim A. almost 8 years
      This work for all laravel versions stackoverflow.com/questions/15586397/…
    • Luzan Baral
      Luzan Baral almost 7 years
      This solution over here worked for me. justcode.me/laravel/…
    • user3151197
      user3151197 over 6 years
    • Snapey
      Snapey over 2 years
      Most 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
    Ali Shahzad over 9 years
    Hi, 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
    Mr. Tomar over 7 years
    After that css not load, bcoz all css are in public and the public is removed from url
  • Muhammad Sadiq
    Muhammad Sadiq over 7 years
    You 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
    Kabir Hossain over 7 years
    Its ok for everything. but artisan command is not working, just it show "Could not open input file: artisan" . Is there any suggestion ?
  • MasoodRehman
    MasoodRehman over 6 years
    This method worked, If you are OK to expose your database credentials to users. localhost/laravel/.env
  • Shadman
    Shadman over 6 years
    This is not a good way to resolve this problem, as you are trying to update in vendors directory which is not good practice.
  • Shadman
    Shadman over 6 years
    you only need to add RewriteRule ^(.*)$ public/$1 [L] in your .htaccess file which you have copied from public directory, by removing this line RewriteRule ^(.*)/$ /$1 [L,R=301]
  • Brigo
    Brigo over 6 years
    I answered below before reading your answer and this must be the accepted answer. No file changes: just a simple, clever rule.
  • Abhinav Saraswat
    Abhinav Saraswat over 6 years
    @Raham what is your current url?
  • Deepesh Thapa
    Deepesh Thapa about 6 years
    Just 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
    FiliusBonacci about 6 years
    the best answer! the only one worked in my example, it should have definitely more up votes
  • rahul singh Chauhan
    rahul singh Chauhan almost 6 years
    Thanks this is work for me. But I want to know it has any security issue or not.
  • Raham
    Raham almost 6 years
    @rahulsinghChauhan my pleasure.Dear I don't know regarding security issue but it ought to be secure.
  • gonzo
    gonzo over 5 years
    What does this rule RewriteRule ^ ^$1 [N] do?
  • Script47
    Script47 over 5 years
    What's the flaws with using this method?
  • Janaka Dombawela
    Janaka Dombawela over 5 years
    Rule number 1: Never edit a core file. Even if it looks easy and nice now, you will pay later.
  • Ferhat KOÇER
    Ferhat KOÇER over 5 years
    @JanakaDombawela i don't think that way because:
  • Ferhat KOÇER
    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
    Arshad Ameen about 5 years
    This is the only one worked for me...thank you so much
  • Manisha
    Manisha about 5 years
    All four ways are good,but i have solved my issue by using first solution.
  • Derk Jan Speelman
    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
    Derk Jan Speelman about 5 years
    This 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
    Luiz Wynne about 5 years
    on 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
    TheLastCodeBender about 5 years
    I really recommend this solution.
  • Samuel Liew
    Samuel Liew about 5 years
    It'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
    CodeConnoisseur almost 5 years
    I 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
    Vincent Decaux almost 5 years
    Worked 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
    Haritsinh Gohil almost 5 years
    It is working fine in production but it is not working in local any suggestion?
  • Derk Jan Speelman
    Derk Jan Speelman almost 5 years
    @HaritsinhGohil for me it's also working fine in development mode, local server, production server, everywhere
  • Haritsinh Gohil
    Haritsinh Gohil almost 5 years
    i 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
    Derk Jan Speelman almost 5 years
    @HaritsinhGohil join this room chat.stackoverflow.com/rooms/196804/laravel-and-htaccess to continue our conversation
  • zanderwar
    zanderwar almost 5 years
    This redirects me to /public/public
  • Victor Ejiogu
    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
    zanderwar almost 5 years
    Project 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
    Derk Jan Speelman almost 5 years
    @LuizWynne take a look at my answer
  • eduardo a
    eduardo a almost 5 years
    I also recommend this solution
  • Ghanshyam Nakiya
    Ghanshyam Nakiya almost 5 years
    This is perfectly working! local and server thank for security help!
  • Shovan
    Shovan almost 5 years
    Hello, @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
    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 the blog folder. Replace RewriteCond %{REQUEST_URI} !^/public/ with RewriteCond %{REQUEST_URI} !^/projects/laravel/blog/public/ and RewriteRule ^(.*)$ /public/$1 [L,QSA] with RewriteRule ^projects/laravel/blog/(.*)$ /projects/laravel/blog/public/$1 [L,QSA] I think that works. Let me know. The RewriteRule works like: RewriteRule pattern target [Flag1,Flag2,Flag3] Apache RewriteRule documentation
  • Varun Ved
    Varun Ved over 4 years
    This answer is underrated. Upvoted for Bold and highlighted Don't. It's working absolutely fine.
  • Prappo
    Prappo over 4 years
    Thank you so much. This is perfect (y)
  • Manoj Singh
    Manoj Singh over 4 years
    it's working fine, but still .env file accessible directly from URL.
  • Admin
    Admin over 4 years
    This is not a perfect answer, rather it is a much unsecure way.
  • Mansour Alnasser
    Mansour Alnasser over 4 years
    The Perfect Answer
  • Raham
    Raham over 4 years
    Thank you,@VishalParkash
  • Senior PHP Developer
    Senior PHP Developer about 4 years
    is it a secure solution?
  • Samik Sengupta
    Samik Sengupta almost 4 years
    This is the correct solution to the problem! Saved me hours.
  • Nhân Trần
    Nhân Trần over 3 years
    thanks a lot, this solution is worked! Why the worked answer not in #2 place
  • mauronet
    mauronet over 3 years
    Please review other answers creating just .htacess file in your root directory, because this answer can expose sensitive information (like .env file)
  • Abd Abughazaleh
    Abd Abughazaleh over 3 years
    Your site you be available for hackers cos .env file we be viewed for everyone .
  • Raitis Kupce
    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
    nassim over 3 years
    This is not secure.
  • Derk Jan Speelman
    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
    Raitis Kupce over 3 years
    @DerkJanSpeelman do you have any resource where this could be learned? To do specifically this task?
  • Riosant
    Riosant over 3 years
    OMG! Its running too fast, You made it dude.
  • Derk Jan Speelman
    Derk Jan Speelman over 3 years
    @RaitisKupce and Riosant medium.com/@crocodile2u/…
  • Yohanim
    Yohanim over 3 years
    I vote for this answer! Use this answer guys
  • Robin Singh
    Robin Singh over 3 years
    Do changes in .htaccess file instead of copy paste file.
  • Chintan Thummar
    Chintan Thummar about 3 years
    I 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
    Pallav Nagar about 3 years
    Thanks for the appreciation.
  • Akbarali
    Akbarali about 3 years
    Thank you very much. The Laravel 8 works very well
  • Qumber
    Qumber almost 3 years
    Keep scrolling for better answer.
  • Abd Abughazaleh
    Abd Abughazaleh almost 3 years
    This not good , .env will be not secure anymore.
  • Private_GER
    Private_GER almost 3 years
    This is an unbelievably bad answer and probably the number one source of hacked Laravel websites.
  • Loganathan Natarajan
    Loganathan Natarajan almost 3 years
    This 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
    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
    Loganathan Natarajan over 2 years
    @DerkJanSpeelman Okay, Thanks
  • cdsaenz
    cdsaenz over 2 years
    Been looking for months for this solution! The only one that works.. even in subfolders! (Using Laravel 8)
  • cdsaenz
    cdsaenz over 2 years
    Just wondering how to avoid /public to be recognized too as a valid url..
  • Snapey
    Snapey over 2 years
    This is incredibly bad advice
  • Snapey
    Snapey over 2 years
    DO NOT DO THIS it is really bad practice
  • Mohammad Salehi
    Mohammad Salehi about 2 years
    @AbdAbughazaleh What if you change .env file permission to 600?
  • Steve Moretz
    Steve Moretz about 2 years
    DON'T USE THIS if you are not looking for more problems than you already have.