phplaravelapache

How to redirect or show custom 404 for css and js folders in Laravel?


How can I redirect users to the website’s root or show a custom 404 page when they attempt to directly access the css and js directories under the public folder by entering a URL in the address bar? For example, visiting these URLs: https://example.com/css and https://example.com/js.

I'm using Laravel 10 with OpenServer 5 (Apache and PHP 8.1). I haven't changed any apache and php settings, everything is default from OpenServer.

When I try to visit https://example.com/css in my project, I get the error shown in the screenshot. Error

In Laravel, I've set up my routes so that when a user navigates to a non-existent route, they are redirected to the homepage (example.com/). This works as expected, but folders inside the public directory (such as css, js, fonts) ignore this behavior and instead return the error shown in the screenshot.

What I want is that if someone tries to access a route like https://example.com/css, they should either be redirected to the homepage (example.com/) or see a nice custom 404 page instead of the error from the screenshot. Can this be done using Laravel?

On real sites like dev.to or laravel.com, if you try to access directories like dev.to/assets or laravel.com/build, they show a clean 404 page, not the Apache error like in my case.

My .htaccess code:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

</IfModule>

Please be patient with me. I’m a complete beginner in development, and instead of making fun of me or acting condescending, please guide me on the right path.


Solution

  • OK, it's been a while since I wrote any Apache rewrite rules and I'm no expert on Laravel routing, but I think you'll get the desired behavior by just commenting out the !-d line in this section:

    # Send Requests To Front Controller...
    # RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    

    Then, if a request comes in for a name that happens to be a valid directory, then it will be handled by Laravel's router, which will do... who knows what with it. Hopefully decide it's not a valid route and serve Laravel's pretty 404 page. Note that this will prevent you from using directory-based URLs in the future, which may not be an issue.

    Alternatively, you might add these two lines between RewriteEngine On and # Handle Authorization Header:

    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L,R=404]
    

    This says, "if the requested URL references a real directory, then stop processing rules and immediately reply with a 404." This will prevent the request from ever making it to your Laravel app, so you'll get the Apache 404 page, not the Laravel 404 page.