Contents
- 1 How to Make Vite Build Work on Filament Page
How to Make Vite Build Work on Filament Page
Context: Filament 3 + Laravel 12 + Vite
Difficulty: Beginner
Prerequisites: Laravel 12, Filament 3, Vite configured
if this article here still cant make vite build used on filament 3. try follow this steps
Overview
When you want to use custom CSS/JS assets (built with Vite) in your Filament 3 admin panel, you need to register them through a custom Service Provider. This article shows you the complete setup.
Problem Statement
Issue: Custom CSS/JS files built with Vite don't appear in Filament pages.
Why This Happens:
- Filament 3 has its own asset management system
- Vite assets need to be registered with Filament's asset manager
- The registration must happen at the right time in the application lifecycle
Solution Architecture
Vite Build → FilamentAsset::register() → Filament Pages
↓ ↓ ↓
resources/js/app.css → Service Provider → Custom Assets Loaded
resources/js/app.js → boot() method in Filament
Step-by-Step Implementation
Step 1: Create FilamentServiceProvider
Location: app/Providers/FilamentServiceProvider.php
Complete Code:
<?php
namespace App\Providers;
use Filament\Support\Facades\FilamentAsset;
use Filament\Support\Assets\Css;
use Filament\Support\Assets\Js;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Vite;
class FilamentServiceProvider extends ServiceProvider
{
public function boot(): void
{
// Register assets only after app is fully booted
$this->app->booted(function () {
FilamentAsset::register([
Css::make('custom-styles', Vite::asset('resources/css/app.css')),
Js::make('custom-scripts', Vite::asset('resources/js/app.js')),
], 'custom');
});
}
}
Code Explanation:
| Component | Purpose |
|---|---|
FilamentAsset::register() |
Register assets with Filament's asset manager |
Css::make('custom-styles', ...) |
Register CSS file with unique name 'custom-styles' |
Js::make('custom-scripts', ...) |
Register JS file with unique name 'custom-scripts' |
Vite::asset(...) |
Resolve Vite asset path (dev or production) |
'custom' |
Asset bundle name (can be any string) |
$this->app->booted(function () {...}) |
Ensure registration happens after full boot |
Step 2: Register Service Provider
Location: bootstrap/providers.php
Complete Code:
<?php
return [
App\Providers\AppServiceProvider::class,
App\Providers\Filament\AdminPanelProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\FilamentServiceProvider::class, // ← Add this line
];
Why This Is Needed:
- Laravel 12 uses
bootstrap/providers.phpto load service providers - Adding your provider here ensures it's loaded during application bootstrap
- Order matters: Place it after core providers but before your custom providers
Step 3: Create Asset Files (If Not Exists)
Vite Entry Point: resources/js/app.js
import './bootstrap';
import '../css/app.css';
// Your custom JS for Filament pages
console.log('Filament custom scripts loaded');
// Example: Custom Alpine.js components
document.addEventListener('alpine:init', () => {
Alpine.data('myComponent', () => ({
open: false,
toggle() {
this.open = !this.open;
}
}));
});
CSS File: resources/css/app.css
/* Tailwind CSS imports */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Your custom styles for Filament */
.filament-custom-heading {
@apply text-2xl font-bold text-gray-900;
}
/* Custom component styles */
.custom-card {
@apply bg-white rounded-lg shadow-sm p-6;
}
Step 4: Configure Vite
Location: vite.config.js
Ensure your Vite config includes the Laravel plugin:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/js/app.js', 'resources/css/app.css'],
refresh: true,
}),
],
});
Note: This is the standard Laravel + Vite setup. No Filament-specific config needed here.
Step 5: Build Assets
Development Mode (Hot reload):
npm run dev
Production Build:
npm run build
This generates:
public/build/assets/- Compiled assetspublic/build/manifest.json- Asset mappingpublic/build/hot- Hot reload file (dev only)
Step 6: Use in Filament Pages
In Your Custom Filament Page:
<?php
namespace App\Filament\Pages;
use Filament\Pages\Page;
class MyCustomPage extends Page
{
protected static string $view = 'filament.pages.my-custom-page';
// Your custom page logic
}
In Blade View (resources/views/filament/pages/my-custom-page.blade.php):
<x-filament-panels::page>
<div class="filament-custom-heading">
<h1>My Custom Page</h1>
</div>
<div class="custom-card">
<div x-data="myComponent">
<button @click="toggle()">Toggle</button>
<div x-show="open">Content</div>
</div>
</div>
</x-filament-panels::page>
How It Works:
- Filament loads the page
- Service Provider registers assets
- Vite resolves
app.jsandapp.css - Assets are injected into Filament's asset bundle
- Your custom CSS/JS is available on the page
Advanced Usage
Multiple Asset Bundles
You can register multiple asset bundles for different purposes:
FilamentAsset::register([
// Admin panel styles
Css::make('admin-styles', Vite::asset('resources/css/admin.css')),
// Student portal styles
Css::make('student-styles', Vite::asset('resources/css/student.css')),
], 'admin');
Conditional Registration
Register assets only on specific environments:
$this->app->booted(function () {
if (app()->environment('production')) {
FilamentAsset::register([
Css::make('minified', Vite::asset('resources/css/app.css')),
], 'production');
}
});
Using in Custom Resources
Add to your Filament Resource:
use Filament\Support\Facades\FilamentAsset;
use Filament\Support\Assets\Js;
class MyResource extends Resource
{
public static function getPages(): array
{
return [
// Your pages
];
}
// Register resource-specific assets
public static function getEloquentQuery(): Builder
{
FilamentAsset::register([
Js::make('resource-scripts', Vite::asset('resources/js/resource.js')),
]);
return parent::getEloquentQuery();
}
}
Troubleshooting
Issue: Assets Not Loading
Symptoms:
- 404 errors for CSS/JS files
- Custom styles not applied
- JavaScript not executing
Solutions:
-
Check if Vite is running (dev mode):
npm run dev -
Clear Filament cache:
php artisan filament:clear-cached-components php artisan config:clear php artisan view:clear -
Verify provider is registered:
php artisan provider:cache php artisan optimize:clear -
Check if assets are built (production):
npm run build ls -la public/build/assets/ -
Verify Vite manifest exists:
cat public/build/manifest.json
Issue: Assets Loading But Not Working
Symptoms:
- Files load (no 404)
- Styles/Scripts don't execute
Solutions:
-
Check browser console for JavaScript errors
-
Verify CSS specificity - Filament styles may override yours:
/* Use !important sparingly */ .my-custom-style { color: red !important; } -
Check Alpine.js timing - Ensure
alpine:initfires after load:document.addEventListener('alpine:init', () => { // Your code here });
Issue: Hot Reload Not Working
Symptoms:
- Changes to CSS/JS not reflecting
- Need to manually refresh
Solutions:
-
Ensure Vite dev server is running:
npm run dev -
Check Vite port (default: 5173):
netstat -an | grep 5173 -
Verify @vite directive in Blade:
@vite(['resources/js/app.js', 'resources/css/app.css'])
Performance Tips
Production Optimization
-
Minify Assets:
npm run build -
Enable Asset Versioning (automatic):
- Vite adds hash to filenames:
app-abc123.js - Cache busting handled automatically
- Vite adds hash to filenames:
-
Use CDN for Static Assets:
- Configure your web server (Nginx/Apache)
- Serve
public/build/via CDN
Development Optimization
-
Exclude Large Dependencies:
Invite.config.js:export default defineConfig({ resolve: { alias: { '@': '/resources/js', }, }, optimizeDeps: { exclude: ['laravel-vite-plugin'], }, }); -
Use Fast Refresh:
- Already enabled by default
- HMR (Hot Module Replacement) preserves component state
Best Practices
1. Asset Organization
resources/
├── css/
│ ├── app.css # Main styles (Tailwind imports)
│ ├── admin.css # Admin-specific styles
│ └── student.css # Student portal styles
└── js/
├── app.js # Main entry point
├── admin.js # Admin-specific scripts
└── student.js # Student portal scripts
2. Naming Conventions
-
CSS Asset Names: Use descriptive kebab-case
- ✅
'admin-styles','student-styles' - ❌
'css1','styles'
- ✅
-
JS Asset Names: Use descriptive kebab-case
- ✅
'custom-scripts','chart-library' - ❌
'js','scripts'
- ✅
3. Asset Bundle Names
The second parameter ('custom') groups related assets:
// Bundle related assets together
FilamentAsset::register([
Css::make('dashboard-css', Vite::asset('resources/css/dashboard.css')),
Js::make('dashboard-js', Vite::asset('resources/js/dashboard.js')),
], 'dashboard-bundle');
4. Lazy Loading
Load heavy assets only when needed:
// In your page class
use Filament\Support\Facades\FilamentAsset;
public function mount(): void
{
// Load chart library only on this page
FilamentAsset::register([
Js::make('charts', Vite::asset('resources/js/charts.js')),
]);
}
Migration from Mix to Vite
If you're migrating from Laravel Mix:
Before (Mix):
// webpack.mix.js
mix.js('resources/js/app.js', 'public/js')
.sass('resources/css/app.css', 'public/css');
After (Vite):
// vite.config.js
export default defineConfig({
plugins: [
laravel({
input: ['resources/js/app.js', 'resources/css/app.css'],
}),
],
});
Provider Changes:
// Old Mix way
{{ mix('css/app.css') }}
// New Vite way (no changes needed in Blade)
@vite(['resources/css/app.css'])
Summary Checklist
- [x] Create
FilamentServiceProvider.php - [x] Register assets in
boot()method - [x] Add provider to
bootstrap/providers.php - [x] Configure
vite.config.js - [x] Create asset files (
app.js,app.css) - [x] Build assets (
npm run buildornpm run dev) - [x] Clear caches (
php artisan optimize:clear) - [x] Test in browser
Related Documentation
- Laravel Vite: https://laravel.com/docs/vite
- Filament 3 Assets: https://filamentphp.com/docs/3.x/panels/assets
- Vite Configuration: https://vitejs.dev/config/
Last Updated: 2026-02-12
Laravel Version: 12
Filament Version: 3.x
Vite Version: 5.x
Quick Reference
Complete Working Example:
// app/Providers/FilamentServiceProvider.php
<?php
namespace App\Providers;
use Filament\Support\Facades\FilamentAsset;
use Filament\Support\Assets\Css;
use Filament\Support\Assets\Js;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Vite;
class FilamentServiceProvider extends ServiceProvider
{
public function boot(): void
{
$this->app->booted(function () {
FilamentAsset::register([
Css::make('custom-styles', Vite::asset('resources/css/app.css')),
Js::make('custom-scripts', Vite::asset('resources/js/app.js')),
], 'custom');
});
}
}
// bootstrap/providers.php
<?php
return [
App\Providers\AppServiceProvider::class,
App\Providers\Filament\AdminPanelProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\FilamentServiceProvider::class,
];
That's it! Your Vite assets will now work seamlessly across all Filament pages.