When you upload a Laravel application to shared hosting, the project may open only when you visit a URL like:
https://yourdomain.com/public
That is not ideal for a production website.
Your visitors should be able to open:
https://yourdomain.com
without adding /public to the URL.
This guide explains how to redirect or rewrite a Laravel application to the public folder using .htaccess.
Why Laravel Uses a Public Folder
Laravel keeps its public entry point inside the public directory.
The main file that handles incoming web requests is:
public/index.php
The public folder also contains public assets such as:
CSS files
JavaScript files
Images
Favicon files
Built frontend assets
Other Laravel folders should normally not be directly accessible from the web.
These include:
appbootstrapconfigdatabaseresourcesroutesstoragevendor
For this reason, the best Laravel hosting setup is to point the domain's document root directly to the public folder.
However, some shared hosting providers do not allow you to change the document root easily. In that case, you can use .htaccess.
Typical Laravel Folder Structure on Shared Hosting
Your Laravel project may look like this:
public_html/
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
│ ├── index.php
│ ├── .htaccess
│ └── build/
├── resources/
├── routes/
├── storage/
├── vendor/
├── .env
├── artisan
└── composer.jsonIf your domain points to:
public_html
then Laravel's index.php is one level deeper inside:
public_html/public
This is why the application may only work when you visit:
https://yourdomain.com/public
Method 1: Redirect Laravel to Public Using Root .htaccess
Create a new .htaccess file inside the main Laravel project directory.
For example:
public_html/.htaccess
Add this code:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>This tells Apache to internally route requests through the Laravel public directory.
After adding this file, visiting:
https://yourdomain.com
should load the Laravel application.
How This .htaccess Rule Works
The first line checks whether Apache's rewrite module is available:
<IfModule mod_rewrite.c>Then it enables URL rewriting:
RewriteEngine OnThis condition prevents Apache from repeatedly adding /public:
RewriteCond %{REQUEST_URI} !^/public/Finally, all requests are internally rewritten to the public folder:
RewriteRule ^(.*)$ public/$1 [L]The visitor still sees:
https://yourdomain.com
instead of:
https://yourdomain.com/public
Make Sure Laravel's Public .htaccess Exists
Laravel normally includes another .htaccess file inside:
public/.htaccess
A typical Laravel Apache configuration looks like this:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{HTTP:X-XSRF-TOKEN} .
RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-TOKEN}]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>Do not remove this file unless you know exactly why you are changing it.
This file is responsible for sending Laravel routes to index.php.
Configure APP_URL
Open your Laravel .env file.
Set:
APP_URL=https://yourdomain.comDo not set:
APP_URL=https://yourdomain.com/publicif you want your application to run from the main domain.
After updating .env, clear Laravel's cached configuration.
Run:
php artisan optimize:clearYou can also run:
php artisan config:clear
php artisan route:clear
php artisan view:clearMethod 2: Point the Domain Document Root Directly to Public
If your hosting panel allows it, this is usually the cleaner solution.
Instead of pointing the domain to:
/home/username/public_htmlset the document root to:
/home/username/public_html/publicThen Apache loads Laravel directly from the correct directory.
This avoids the need for a root-level rewrite.
Which Method Is Better?
Document Root Method
Use this when your hosting panel lets you change the domain root.
Advantages:
Cleaner configuration
Better Laravel security
No extra root rewrite
Public files are served directly
Private Laravel files remain outside the web root
.htaccess Rewrite Method
Use this when:
Shared hosting forces the domain to use
public_htmlYou cannot change the document root
Your Laravel project is already inside
public_htmlYou need a quick compatible setup
Avoid Moving index.php Unless Necessary
Some tutorials suggest moving:
public/index.php
into the Laravel project root.
This can work with additional path changes, but it is usually not the preferred deployment approach.
Laravel is designed to use the public folder as the web-accessible directory.
Keeping that structure makes future upgrades and maintenance easier.
Do Not Expose the .env File
Your .env file can contain sensitive information such as:
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
APP_KEY=
MAIL_PASSWORD=It should never be publicly accessible.
Test this URL:
https://yourdomain.com/.env
It should return an error, forbidden response, or not found page.
It should never display the contents of your .env file.
Check File and Folder Permissions
Laravel needs write access to certain directories.
Common directories that must be writable are:
storage/
bootstrap/cache/Typical Linux permissions may be:
chmod -R 775 storage
chmod -R 775 bootstrap/cacheThe correct owner and permissions depend on your hosting environment.
Avoid using 777 unless your hosting provider specifically requires it and you understand the security implications.
Create the Laravel Storage Link
If your application stores uploaded files using Laravel's public disk, create the storage symbolic link:
php artisan storage:linkThis normally creates:
public/storagepointing to:
storage/app/publicThen files can be accessed using URLs such as:
https://yourdomain.com/storage/image.jpg
If public/storage Already Exists
You may see an error like:
The [public/storage] link already exists.First check whether it is a symbolic link:
ls -l public/storageIf it is a normal directory instead of a symbolic link, you may need to remove or rename that directory before running:
php artisan storage:linkBe careful before deleting anything if the directory contains uploaded customer files.
Fix Laravel Assets Loading From /public
If your CSS, JavaScript, or images are trying to load from URLs such as:
https://yourdomain.com/public/css/app.css
check your asset configuration.
Use Laravel helpers such as:
{{ asset('css/app.css') }}instead of hardcoding:
/public/css/app.cssFor Vite applications, use Laravel's Vite integration where appropriate.
Laravel Routes Return 404
If the home page works but routes such as:
/login
/dashboard
/products
return 404 errors, Apache rewriting may not be enabled.
Check that:
mod_rewriteis enabledpublic/.htaccessexistsApache allows
.htaccessoverridesYour document root is correct
If you manage the Apache server directly, the virtual host may need:
<Directory /var/www/example/public>
AllowOverride All
Require all granted
</Directory>Then restart Apache.
Laravel Shows 500 Internal Server Error
A 500 error can be caused by:
Incorrect PHP version
Missing PHP extensions
Incorrect file permissions
Invalid
.htaccessMissing Composer dependencies
Wrong
.envsettingsMissing
APP_KEYLaravel cache permissions
Check the Laravel log:
storage/logs/laravel.logIf you have SSH access, you can also check the server error log.
Run Composer Install
After uploading a Laravel application, make sure dependencies are installed.
Run:
composer install --no-dev --optimize-autoloaderFor production, you can also run:
php artisan optimizeGenerate APP_KEY
If your .env file does not already contain a valid application key, run:
php artisan key:generateDo not regenerate the key on an existing production application without understanding the impact, because encrypted data and sessions can be affected.
Configure the Database
Update your .env file:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database
DB_USERNAME=your_username
DB_PASSWORD=your_passwordThen test the application.
If required, run migrations:
php artisan migrate --forceOnly run production migrations when you know they are appropriate for that deployment.
Enable HTTPS
Once the domain is working, install or enable SSL.
Update:
APP_URL=https://yourdomain.comThen clear the application cache:
php artisan optimize:clearYour site should load through:
https://yourdomain.com
Recommended Laravel Deployment Checklist
Before considering your Laravel application ready, check:
Domain points to the correct server
Document root points to
public, or root.htaccessrewrites topublic.envis not publicly accessibleComposer dependencies are installed
APP_KEYexistsDatabase configuration is correct
storageis writablebootstrap/cacheis writableStorage link is configured if required
SSL is enabled
APP_URLuses the correct HTTPS domainLaravel caches are refreshed
Login and application routes work
CSS and JavaScript files load correctly
Example Complete Setup
Suppose your Laravel application is located here:
/home/ceylonweb/public_html/and the project contains:
/home/ceylonweb/public_html/public/index.phpYour root .htaccess would be:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>Your .env would contain:
APP_URL=https://example.comThen clear Laravel's caches:
php artisan optimize:clearNow opening:
https://example.com
should load the Laravel application without showing /public in the browser address.
Frequently Asked Questions
Why does my Laravel website only work with /public?
Your domain is probably pointing to the Laravel project root instead of the public directory.
The correct document root should normally be the Laravel public folder.
Can I remove /public from a Laravel URL using .htaccess?
Yes.
A root .htaccess rule can internally rewrite requests to the public folder when you cannot change your domain's document root.
Should I redirect or rewrite to public?
An internal rewrite is usually preferable because visitors continue seeing the clean domain URL.
For example:
https://example.com
instead of:
https://example.com/public
Is it safe to put Laravel inside public_html?
It can work, but the preferred setup is to expose only Laravel's public directory to the web.
If the complete project is under public_html, make sure sensitive files such as .env are protected.
What is the best Laravel document root?
The document root should normally point to:
/path/to/laravel/publicWhy do Laravel routes return 404 on shared hosting?
The most common causes are missing Apache rewrite support, an incorrect .htaccess file, or an incorrect document root.
Why are Laravel CSS and JavaScript files not loading?
Check your asset URLs and make sure they are not hardcoded with /public.
Use Laravel's asset or Vite helpers where appropriate.
Do I need to run php artisan storage?
You need it if your application uses Laravel's public storage disk and must expose files from storage/app/public.
Need Laravel Hosting Help?
If you are hosting a Laravel application and need a suitable hosting environment, Ceylon Web Servers provides hosting options for websites and web applications.
Available options include:
Shared Hosting
Reseller Hosting
VPS Hosting
For larger Laravel applications or projects that require more server control, a VPS may be more suitable.
Website: ceylonwebservers.com
Call / WhatsApp: 070 244 7722