Upgrading
From 1.x to 2.x
Version 2.x includes several breaking changes. Follow this guide to upgrade your application.
Requirements
| Dependency | Version |
|---|---|
| PHP | ^8.3 |
| Laravel | ^12.0 |
| Filament | ^5.0 |
| Livewire | ^4.0 |
| Tailwind CSS | ^4.0 |
Step 1: Update qore-admin-base
Update your composer.json to require version 2.x:
"qore-works-business/qore-admin-base": "^2.0"Dev Dependency Bumps
Upgrading to qore 2.x pulls in Livewire ^4.1 (via qore-frontend) and pest-plugin-qore v3.0 (which requires Pest ^4.0). This triggers a cascade of required version bumps in your dev dependencies:
| Package | Old Version | New Version | Why |
|---|---|---|---|
qore-works-business/pest-plugin-qore | ^2.0 | ^3.0 | Required for Pest ^4.0 support |
pestphp/pest | ^3.0 | ^4.0 | Required by pest-plugin-qore ^3.0 |
pestphp/pest-plugin-laravel | ^3.1 | ^4.0 | Required by pestphp/pest ^4.0 |
pestphp/pest-plugin-livewire | ^3.0 | ^4.0 | Required by livewire/livewire ^4.1 |
Note:
qore-works-business/pest-plugin-qorelatest version is^3.0(not^4.0).
Step 2: Run Filament Automated Upgrade
The first step to upgrade your Filament app is to run the automated upgrade script. This script will automatically upgrade your application to the latest version of Filament and make changes to your code, which handles most breaking changes:
composer require filament/upgrade:"^5.0" -W --dev
vendor/bin/filament-v5
# Run the commands output by the upgrade script, they are unique to your app
composer require filament/filament:"^5.0" -W --no-update
composer updateImportant: Some plugins you're using may not be available in v5 just yet. You could temporarily remove them from your
composer.jsonfile until they've been upgraded.
Windows PowerShell: Replace
^with~in version constraints if experiencing installation issues.
Step 3: Locale Switch Migration
The locale switch functionality is now built into qore-admin-base. Remove the external package dependency if you are not using it.
Remove from composer.json:
// Remove this from "require"
"bezhansalleh/filament-language-switch"Remove from config/qore.php:
// Remove this section if present
'language_switch' => [
'locales' => ['nl', 'en'],
],Update your Panel Service Provider:
// Before (1.x)
QoreAdminBasePlugin::make()
->setFaqResource(true)
// After (2.x)
QoreAdminBasePlugin::make()
->setFaqResource(true)
->setLocaleSwitch(['nl', 'en'])Update event imports (if used):
// Before
use BezhanSalleh\LanguageSwitch\Events\LocaleChanged;
// After
use QoreWorksBusiness\QoreAdminBase\Events\LocaleChanged;Step 4: Manual Filament 5 Changes
The automated upgrade tool handles most changes, but some files may need manual updates. Review your Resources, Pages, and custom components for these patterns:
Actions Namespace
ALL table action classes have moved from Filament\Tables\Actions\* to Filament\Actions\*. This includes CreateAction, EditAction, DeleteAction, ForceDeleteAction, RestoreAction, BulkActionGroup, DeleteBulkAction, ForceDeleteBulkAction, RestoreBulkAction, and all others.
// Before
use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\CreateAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\ForceDeleteAction;
use Filament\Tables\Actions\RestoreAction;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Actions\ForceDeleteBulkAction;
use Filament\Tables\Actions\RestoreBulkAction;
// After — ALL moved to Filament\Actions
use Filament\Actions\Action;
use Filament\Actions\CreateAction;
use Filament\Actions\EditAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\ForceDeleteAction;
use Filament\Actions\RestoreAction;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\RestoreBulkAction;Static Property Types
Filament 5 changed the types of static properties on Resource and Page classes. If your project overrides these properties, the type declarations must be updated or PHP will throw a fatal error:
// Before
protected static ?string $navigationGroup = 'Platform';
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
// After
use BackedEnum;
use UnitEnum;
protected static string | UnitEnum | null $navigationGroup = 'Platform';
protected static string | BackedEnum | null $navigationIcon = 'heroicon-o-rectangle-stack';Form to Schema
// Before
use Filament\Forms\Form;
public static function form(Form $form): Form
// After
use Filament\Schemas\Schema;
public static function form(Schema $schema): SchemaLayout Components
// Before
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Grid;
// After
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Grid;Get/Set Utilities
// Before
use Filament\Forms\Get;
use Filament\Forms\Set;
// After
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;Auth Pages
// Before
use Filament\Pages\Auth\Login;
// After
use Filament\Auth\Pages\Login;Dashboard Page
// Before
use Filament\Pages\Page;
class Dashboard extends Page
{
protected function getWidgets(): array { ... }
}
// After
use Filament\Pages\Dashboard as FilamentDashboard;
class Dashboard extends FilamentDashboard
{
public function getWidgets(): array { ... } // Must be public
}For full details, see the Filament 5 Upgrade Guide.
Step 5: Update Tests for Filament 5
Filament 5 introduces TestAction objects for testing table actions. The old callTableAction() still works but the new callAction() with TestAction is the recommended pattern.
Testing Table Actions
use Filament\Actions\Testing\TestAction;
// Table header actions (e.g. create) — no record, just mark as table action
// Before:
$livewire->callTableAction(CreateAction::class, null, $data);
// After:
$livewire->callAction(TestAction::make(CreateAction::class)->table(), $data);
// Table row actions (e.g. detach, edit, delete) — pass the record
// Before:
$livewire->callTableAction('detach', $record);
// After:
$livewire->callAction(TestAction::make('detach')->table($record));Row Action ->model() Breaking Change
Filament 5 enforces record type checking via ensureCorrectRecordType(). If a row action has ->model(Company::class) but the table record is a Person, getRecord() returns null and the action fails.
Fix: Remove ->model() from row actions that operate on the table's related model:
// Before (broken in Filament 5)
DetachAuditAction::make()->model(Company::class),
// After
DetachAuditAction::make(),Note:
->model()on header actions likeAttachAuditActionis still valid because the model is used for record search/selection, not record type checking.
CountrySelect in Tests
Use known-valid country codes instead of fake()->countryCode():
// Before (generates codes not in LaravelLang list)
'country_of_birth' => strtolower(fake()->countryCode()),
// After
'country_of_birth' => fake()->randomElement(['nl', 'de', 'be', 'fr', 'gb']),Step 6: Livewire 4 Updates
After Filament is upgraded, review the Livewire 4 Upgrade Guide for any remaining updates.
Events (most common change):
// Before
$this->emit('eventName');
// After
$this->dispatch('eventName');wire:model ignores child element events by default. Add .deep to restore v3 behavior:
<div wire:model.deep="value">Configuration (config/livewire.php):
'layout'→'component_layout''lazy_placeholder'→'component_placeholder'
Step 7: Tailwind CSS v4 Theme Migration
Tailwind CSS v4 uses CSS-first configuration. The old JS-based config with Filament presets no longer works.
Filament Admin Theme
The Filament admin theme CSS file needs updating. The tailwind.config.preset from the filament package no longer exists in Filament 5.
/* Before (Tailwind CSS v3) */
@import '../../../../vendor/filament/filament/resources/css/theme.css';
/* tailwind config */
@config './tailwind.config.js';/* After (Tailwind CSS v4) */
@import '../../../../vendor/filament/filament/resources/css/theme.css';
@source '../../../../app/Application/Admin/**/*';
@source '../../../../resources/views/application/admin/**/*';You can remove the old tailwind.config.js file that referenced the Filament preset.
Portal CSS
Portal CSS should use @source directives instead of JS config content arrays:
/* Before (Tailwind CSS v3 — tailwind.config.js) */
content: ['../../../../vendor/qore-works-business/qore-frontend/resources/views/**/*.blade.php']
/* After (Tailwind CSS v4 — app.css) */
@import "tailwindcss";
@source '../../../../vendor/qore-works-business/qore-frontend/resources/views/**/*.blade.php';
@source '../../../../resources/views/application/portal/**/*.blade.php';Step 8: Update Project Files
Update default stub files and composer scripts using the maintenance commands:
# Update stub files (tests, config) - safe mode first
php artisan qore-admin-base:publish-stubs
# Add missing composer scripts
php artisan qore-admin-base:update-composer-scriptsTip: Run
publish-stubswithout--forcefirst to see which files would be updated, then use--forceto overwrite specific files as needed.
See the Commands page for full details on these commands.
Step 9: Clear Caches
php artisan optimize:clear
php artisan filament:clear-cached-componentsQuick Search Commands
Find files that may still need manual updates:
# Actions namespace
grep -r "use Filament\\Tables\\Actions\\" --include="*.php" .
# Layout components
grep -r "use Filament\\Forms\\Components\\Section" --include="*.php" .
# Get/Set utilities
grep -r "use Filament\\Forms\\Get" --include="*.php" .
# Livewire emit
grep -r "->emit(" --include="*.php" .