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:

âś… This method works for Laravel 9, Laravel 10, and newer versions


Prerequisites

Before proceeding, ensure you have:


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


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:


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


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:


Common Issues and Fixes

ProblemSolution
Assets not loadingRebuild Vite assets
Storage files 404Re-run storage:link
HMR not workingSet correct HMR host
Cached pathsRun 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:

By updating Laravel’s service container, bootstrap configuration, filesystem links, and Vite settings, you ensure long-term stability and SEO-friendly asset delivery.

One Response

Leave a Reply

Your email address will not be published. Required fields are marked *