Where do javascript and css files go in a laravel project
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Where Do JavaScript and CSS Files Go in a Laravel Project? A Developer's Guide
As developers building applications with Laravel, one of the most fundamental questions we face early on is: where do our static assets—our CSS, JavaScript, images, and fonts—actually reside, and how does Laravel serve them correctly? Many beginners run into frustrating 404 errors when trying to place these files in the public directory, leading to confusion about routing and file access.
This post will walk you through the correct structure, address the pitfalls you encountered, and show you the modern, recommended way to handle asset compilation within a Laravel environment.
The Fundamental Structure: Understanding the public Directory
In a standard Laravel installation, the entire web-accessible portion of your application must reside within the public directory. This is because this directory is what the web server (Apache, Nginx) is configured to serve directly to external users.
The rule of thumb for static assets in Laravel is simple: anything that needs to be accessed via a direct URL should be placed in public.
Therefore, the correct locations for your compiled CSS and JavaScript files are typically:
- CSS Files: Stored in a subdirectory within
public, such aspublic/css/. - JavaScript Files: Stored in a subdirectory within
public, such aspublic/js/.
When you place these files here, they become directly accessible via their URL (e.g., /css/app.css or /js/app.js). This is the standard convention for serving static content on any web server setup.
Why You Encountered 404 Errors
Your experience with the 404 errors suggests a misunderstanding of how Laravel handles routing versus how raw file access works, especially when using a custom .htaccess file.
When you use the structure:
RewriteRule ^ index.php [L]
This rule tells the server that any request should be routed through index.php. This is crucial for Laravel's MVC routing system (where routes define what content to display). By placing assets directly in subdirectories like /public/js/, you are telling the browser to look for a file path that doesn't map to a defined route, causing the server to fail when it can't find a corresponding entry point handled by Laravel.
The key takeaway is this: For basic static files served directly by the web server (like images or raw CSS), placing them in public is correct, provided your web server configuration correctly handles static file serving alongside Laravel's routing. For modern complexity, we often delegate this task to a dedicated build tool.
The Modern Approach: Leveraging Vite for Asset Management
While placing files directly in public/js works for tiny projects, modern Laravel development heavily relies on asset bundling and compilation, typically managed by Vite. This approach ensures that your assets are processed (minified, transpiled, versioned) before they are served, which dramatically improves performance and maintainability.
Instead of manually managing public/js files, you configure Vite to compile your source files (usually in resources/js) into a single output file during the build process.
Step 1: Configure Source Files
Place your raw JavaScript/CSS files where your tooling expects them, typically in resources/js/ and resources/css/.
Step 2: Define Assets in Blade
In your main Blade layout file (resources/views/layouts/app.blade.php), you use the @vite directive. This single line delegates the entire asset loading process to Vite, ensuring that Laravel handles the correct dependency mapping and pathing automatically.
Example using @vite:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Laravel Asset Demo</title>
{{-- Vite handles linking the compiled CSS/JS files --}}
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
This method ensures that your assets are correctly bundled and served, adhering to best practices for large-scale applications. For more detailed insights into managing resources within the Laravel ecosystem, we recommend exploring official documentation, such as what is provided by the team at laravelcompany.com.
Conclusion
To summarize: place raw, uncompiled assets in public/ if you require direct access (though this is less common now). However, for any serious Laravel project, the best practice is to adopt a build pipeline like Vite. This separates the source of your code (resources) from the publicly accessible compiled output, resulting in cleaner code, better performance, and reliable asset management. Embrace tools that automate this process; it saves significant development time!