When deploying a Laravel application on shared hosting, one common issue is that the website only works when /public is included in the URL. For example, instead of accessing https://example.com, you have to visit https://example.com/public.
This usually happens because Laravel’s web entry point is located inside the public directory, while the hosting account’s document root points to the project’s root directory.
The good news is that Apache rewrite rules can help route requests to the correct location. In this tutorial, we’ll look at how to configure .htaccess, understand how the rewrite rules work, and explore a safer deployment approach for Laravel applications.
Why Does Laravel Use the Public Directory?
Laravel separates application files from publicly accessible files. The public directory contains the index.php entry point, public assets, and other files intended to be served by the web server.
A typical Laravel project structure looks like this:
laravel-app/
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
│ ├── .htaccess
│ ├── index.php
│ └── build/
├── resources/
├── routes/
├── storage/
├── vendor/
├── .env
├── artisan
└── composer.json
When a domain points to the Laravel project root instead of the public directory, Apache may not execute Laravel’s front controller correctly.
The goal is to make requests reach the public directory without requiring visitors to include /public in the browser’s address bar.
Method 1: Configure the Root .htaccess File
If your hosting provider does not allow you to change the document root, you may be able to use a root-level .htaccess file as a workaround.
Create or edit the .htaccess file in the Laravel project root, alongside the artisan file.
Add the following configuration:
<IfModule mod_rewrite.c>
RewriteEngine On
# Avoid rewriting requests that already target /public
RewriteCond %{REQUEST_URI} !^/public(?:/|$) [NC]
# Route requests to the public directory
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
Save the file and test your website.
If the configuration is compatible with your hosting environment, requests can be internally rewritten to the public directory without changing the URL displayed in the browser.
Important: This configuration is a workaround, not a complete security solution. If the entire Laravel project remains inside a publicly accessible directory, sensitive files may still be exposed through direct requests unless access is properly restricted.
Understanding the Rewrite Rules
Let’s break down the configuration to understand what each directive does.
1. Enable Apache URL Rewriting
RewriteEngine On
This enables URL rewriting for the current directory, provided Apache’s mod_rewrite module is available and the server permits the relevant overrides.
2. Prevent Rewriting Requests Already Under Public
RewriteCond %{REQUEST_URI} !^/public(?:/|$) [NC]
This condition excludes requests whose URI already begins with /public as a complete path segment. It helps avoid repeatedly rewriting requests that already target the public directory.
The exact behavior can depend on the hosting environment, so test it before deploying the configuration to a production website.
3. Rewrite Requests to the Public Directory
RewriteRule ^(.*)$ public/$1 [L]
This rule internally maps a request to a corresponding path under public.
For example, a request to /about is mapped to public/about. If the requested file or directory does not exist, Laravel’s own rewrite rules in public/.htaccess can route the request to public/index.php.
The browser normally continues displaying the original URL because this is an internal rewrite rather than an external redirect.
Method 2: Point the Document Root to Laravel’s Public Directory
The recommended deployment method is to configure your domain’s document root to point directly to Laravel’s public directory.
For example:
/home/username/laravel-app/public
This approach allows Apache to serve the intended public entry point without exposing the rest of the project through the web root.
If you have access to your hosting control panel, look for the domain’s document root or website root setting. The exact menu name depends on your hosting provider.
After changing the document root, confirm that the domain serves the correct public/index.php file and that the existing public/.htaccess file is preserved.
This method is generally preferable to rewriting every request from the project root.
Method 3: Keep the Laravel Project Outside the Public Web Root
If your hosting structure permits it, keep the Laravel application outside the publicly accessible directory.
For example:
/home/username/
├── laravel-app/
│ ├── app/
│ ├── bootstrap/
│ ├── config/
│ ├── public/
│ ├── routes/
│ ├── storage/
│ ├── vendor/
│ └── .env
└── public_html/
Configure the domain to serve the contents of laravel-app/public, or use a hosting setup that safely maps the domain to that directory.
Do not simply copy the contents of Laravel’s public directory into public_html without adjusting the entry point and deployment structure correctly. If you use a customized structure, verify that index.php references the correct application paths.
Common Laravel .htaccess Errors
Even when the rewrite rules look correct, some hosting environments require additional configuration.
Internal Server Error (500)
A 500 error may indicate invalid directives, unsupported rewrite settings, or an Apache configuration problem.
To troubleshoot:
- Check your hosting error logs.
- Confirm that Apache’s
mod_rewritemodule is enabled. - Check whether
.htaccessoverrides are allowed. - Review recent changes and restore the last working configuration if necessary.
Avoid changing multiple server settings at once, as that makes the root cause harder to identify.
Page Not Found (404)
If the homepage loads but application routes return 404 errors, verify that public/.htaccess exists and that Laravel’s route definitions are correct.
You should also confirm that the domain points to the intended project and that the rewrite rules do not conflict with existing hosting rules.
CSS, JavaScript, or Images Are Missing
Check that your assets are available inside the public directory and that the generated URLs point to the correct paths.
For Laravel applications using Vite, make sure the production assets have been built and deployed. Also review any custom asset URL or base-path configuration.
The Website Still Shows /public
If /public remains visible in the browser, check whether the request is reaching the intended .htaccess file and whether the web server allows the rewrite directives to run.
If your domain already points to Laravel’s public directory, a root-level rewrite is generally unnecessary.
Security Checklist Before Deployment
Before publishing a Laravel application, verify these important settings:
- Keep
.env, application source code, and dependency files inaccessible to public requests. - Do not expose Git metadata, database backups, logs, or configuration files.
- Enable HTTPS for the domain.
- Set
APP_DEBUG=falsein production. - Ensure
storageandbootstrap/cachehave appropriate permissions. - Confirm that only intended public assets are served by the web server.
A rewrite rule by itself does not guarantee that sensitive files are protected. Correct document-root configuration and appropriate server access controls are essential.
Final Thoughts
Configuring .htaccess can help resolve Laravel URL issues on Apache shared hosting, especially when the hosting provider does not allow document-root changes.
However, pointing the domain directly to Laravel’s public directory remains the preferred approach. It provides a cleaner deployment structure and reduces the risk of accidentally exposing internal application files.
If you are unsure which method is appropriate, check your hosting configuration before making changes.
For more information, consult the official Laravel Deployment Documentation.
With the right configuration, you can serve your Laravel application without requiring visitors to include /public in the URL while maintaining a safer deployment structure.


