Skip to content

Upgrading ​

From 1.x to 2.x ​

Version 2.x includes several breaking changes. Follow this guide to upgrade your application.

Requirements ​

DependencyVersion
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:

json
"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:

PackageOld VersionNew VersionWhy
qore-works-business/pest-plugin-qore^2.0^3.0Required for Pest ^4.0 support
pestphp/pest^3.0^4.0Required by pest-plugin-qore ^3.0
pestphp/pest-plugin-laravel^3.1^4.0Required by pestphp/pest ^4.0
pestphp/pest-plugin-livewire^3.0^4.0Required by livewire/livewire ^4.1

Note: qore-works-business/pest-plugin-qore latest 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:

bash
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 update

Important: Some plugins you're using may not be available in v5 just yet. You could temporarily remove them from your composer.json file 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:

json
// Remove this from "require"
"bezhansalleh/filament-language-switch"

Remove from config/qore.php:

php
// Remove this section if present
'language_switch' => [
    'locales' => ['nl', 'en'],
],

Update your Panel Service Provider:

php
// Before (1.x)
QoreAdminBasePlugin::make()
    ->setFaqResource(true)

// After (2.x)
QoreAdminBasePlugin::make()
    ->setFaqResource(true)
    ->setLocaleSwitch(['nl', 'en'])

Update event imports (if used):

php
// 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.

php
// 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:

php
// 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 ​

php
// Before
use Filament\Forms\Form;
public static function form(Form $form): Form

// After
use Filament\Schemas\Schema;
public static function form(Schema $schema): Schema

Layout Components ​

php
// 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 ​

php
// Before
use Filament\Forms\Get;
use Filament\Forms\Set;

// After
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;

Auth Pages ​

php
// Before
use Filament\Pages\Auth\Login;

// After
use Filament\Auth\Pages\Login;

Dashboard Page ​

php
// 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 ​

php
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:

php
// Before (broken in Filament 5)
DetachAuditAction::make()->model(Company::class),

// After
DetachAuditAction::make(),

Note: ->model() on header actions like AttachAuditAction is 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():

php
// 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):

php
// Before
$this->emit('eventName');

// After
$this->dispatch('eventName');

wire:model ignores child element events by default. Add .deep to restore v3 behavior:

blade
<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.

css
/* Before (Tailwind CSS v3) */
@import '../../../../vendor/filament/filament/resources/css/theme.css';

/* tailwind config */
@config './tailwind.config.js';
css
/* 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:

css
/* 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:

bash
# 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-scripts

Tip: Run publish-stubs without --force first to see which files would be updated, then use --force to overwrite specific files as needed.

See the Commands page for full details on these commands.

Step 9: Clear Caches ​

bash
php artisan optimize:clear
php artisan filament:clear-cached-components

Quick Search Commands ​

Find files that may still need manual updates:

bash
# 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" .