Im getting CSS and JS not found laravel 9 app

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Fixing CSS and JS Not Found Errors in Laravel: A Deep Dive for Modern Applications

As a senior developer working with the Laravel ecosystem, one of the most common hurdles developers face is correctly managing asset loading. You've set up your framework—Laravel 9, Livewire, Jetstream, and Tailwind CSS—but when you try to inject custom CSS or JavaScript files, they refuse to load. This often leads to frustrating "404 Not Found" errors, even when the file exists locally on your server.

This post will diagnose why your custom assets might be failing to load while default assets succeed, and provide a robust solution based on Laravel's asset management system.

The Root Cause: Asset Compilation vs. Direct Linking

The discrepancy you are observing—where app.css works but custom files like tailwind.output.css and init-alpine.js fail—almost always points to a mismatch between how you are referencing the file (using asset()) and how Laravel is configured to publish or compile those assets.

In modern Laravel applications, especially those using tools like Vite (which powers the default setup for newer Laravel versions), assets stored in resources/css and resources/js are not directly served as raw files from the public directory by default. Instead, they must go through a compilation step.

  1. Default Assets (app.css): When you use mix('css/app.css') or sometimes asset('css/app.css'), Laravel knows to pull these files from the compiled output folder (usually public/build). This works because the build process has already run and placed the finalized, publicly accessible files there.
  2. Custom Assets (tailwind.output.css, init-alpine.js): If these files are generated by a PostCSS setup (like Tailwind) or are custom scripts, they must be explicitly compiled before they can be served via the standard asset pipeline. If you link them directly using asset(), but those files haven't been processed and moved to the public directory, the browser cannot find them, resulting in a 404 error.

The Solution: Leveraging Vite for Asset Management

The most robust way to handle CSS and JavaScript in a modern Laravel application is by utilizing Vite. Vite handles bundling, transpilation, and asset management seamlessly. You should stop trying to reference compiled files directly via asset() unless you are serving raw static files. Instead, rely on the build process.

Step 1: Ensure Your Build Process is Correct

For Tailwind CSS, the correct workflow involves using PostCSS within your Vite configuration (vite.config.js) to generate the final output. The resulting compiled CSS file must be placed in a location that Vite knows how to serve, typically public/build.

If you are generating custom files manually, ensure they follow the standard structure:

resources/css/
├── app.css          (Default entry point)
└── tailwind.input.css (Input file for PostCSS/Tailwind compilation)

resources/js/
├── app.js           (Default entry point)
└── init-alpine.js   (Your custom script)

Step 2: Refactor Blade Referencing

Instead of referencing the potentially uncompiled output directly, you should reference the main entry points that Vite is configured to handle. For external scripts or components that need to be loaded outside the standard bundling process (like your init-alpine.js), ensure they are correctly placed in the public directory if they are static assets, or load them via a CDN if appropriate.

If you must load a specific custom file dynamically, use the asset helper carefully:

<!-- Correct way to reference publicly served files -->
<link rel="stylesheet" href="{{ asset('css/app.css') }}"> 

{{-- If init-alpine.js is meant to be static and directly in public --}}
<script src="{{ asset('js/init-alpine.js') }}" defer></script> 

If the issue persists, it suggests that your custom files are not being correctly integrated into the Vite build process. Always consult the official documentation for Laravel's asset handling practices; understanding the underlying architecture is key to solving these integration issues. For deeper insights into Laravel architecture and best practices, reviewing resources from laravelcompany.com is highly recommended.

Conclusion

The issue of missing CSS/JS files in a Laravel application is rarely about file existence; it's usually about the asset pipeline configuration. By shifting your strategy to rely on Vite for bundling and ensuring that all custom assets are processed through the correct build steps before being served via asset(), you ensure consistency and reliability. Focus on making sure your asset compilation process correctly maps your resources files to the public directory. Happy coding!