If you are deploying Laravel on shared hosting like Hostinger or cPanel servers, you may notice that the document root is public_html instead of Laravel’s default public directory. This mismatch can cause asset loading issues, broken storage links, or security concerns if not handled correctly.
In this expert Laravel tutorial, you will learn how to change the Laravel public folder to public_html safely, including support for Vite, storage symlinks, and Hot Module Replacement (HMR).
Why Change Laravel’s Public Folder to public_html?
Many hosting providers enforce public_html as the web root. Common reasons to change it include:
- Compatibility with cPanel / shared hosting
- Avoiding unnecessary symlinks
- Improved application security
- Cleaner project structure
- Proper Vite asset resolution
✅ This method works for Laravel 9, Laravel 10, and newer versions
Prerequisites
Before proceeding, ensure you have:
- Laravel 9+
- PHP 8 or higher
- Node.js (for Vite)
- Access to project files (SSH or FTP)
Step 1: Override the Public Path in AppServiceProvider
Laravel internally resolves the public directory using the service container. We override it to point to public_html.
📍 File: app/Providers/AppServiceProvider.php
/**
* Overwrite public folder.
*/
$this->app->bind('path.public', function () {
return base_path('public_html');
});
Why This Is Important
- Updates
public_path()globally - Ensures asset helpers reference
public_html - Prevents broken file paths in production
Step 2: Configure the Public Path in bootstrap/app.php
Modern Laravel versions define the public path during application bootstrapping.
📍 File: bootstrap/app.php
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
$app = Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'/admin/upload',
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})
->registered(function ($app) {
$app->usePublicPath(
path: realpath(base_path('/../public_html'))
);
})
->create();
$app->bind('path.public', function () {
return base_path().'/public_html';
});
return $app;
SEO Benefit
Ensures:
- Proper asset loading
- No broken CSS or JS files
- Faster page rendering (Core Web Vitals)
Step 3: Fix Storage Symlinks (storage:link)
Laravel’s file uploads rely on the public directory. Update the symlink configuration accordingly.
📍 File: config/filesystems.php
'links' => [
app()->basePath('public_html/storage') => storage_path('app/public'),
],
Then run:
php artisan storage:link
Result
Uploads will now be accessible at:
/public_html/storage
Step 4: Update Vite Configuration for public_html
Vite must be aware of the new public directory for Hot Module Replacement (HMR) and production builds.
📍 File: vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/js/app.js'],
publicDirectory: 'public_html',
}),
],
build: {
outDir: 'public_html/build',
},
server: {
hmr: {
host: 'localhost',
},
},
});
Why This Matters for SEO
- Prevents broken assets
- Improves Lighthouse performance scores
- Ensures proper asset versioning
Step 5: Rename the Public Folder
Rename Laravel’s default public directory:
mv public public_html
Make sure your server document root points to:
/your-project/public_html
Clear Cache and Rebuild Assets
After all changes, run:
php artisan optimize:clear
npm run build
This ensures:
- Fresh configuration
- Clean route & view caches
- Correct asset compilation
Common Issues and Fixes
| Problem | Solution |
|---|---|
| Assets not loading | Rebuild Vite assets |
| Storage files 404 | Re-run storage:link |
| HMR not working | Set correct HMR host |
| Cached paths | Run optimize:clear |
Final Thoughts
Changing Laravel’s public folder to public_html is 100% safe and production-ready when configured properly. This setup is ideal for:
- Shared hosting
- cPanel environments
- Secure Laravel deployments
By updating Laravel’s service container, bootstrap configuration, filesystem links, and Vite settings, you ensure long-term stability and SEO-friendly asset delivery.
Leave a Reply to A WordPress Commenter Cancel reply