Laravel-13-Tutorial #4: Admin-Panel mit Filament einrichten
geprüft am 7 September 2026 · 6 Min.
Laravel bringt kein Back-Office mit. Diese Serie setzt jetzt auf Filament: composer require filament/filament, danach php artisan filament:install --panels. Voyager, in den früheren Fassungen verwendet, ist auf Packagist als abandoned markiert und lässt sich unter Laravel 13 nicht mehr installieren.
Laravel bringt kein Back-Office mit. Du musst eines auswählen, und diese Entscheidung bindet das Projekt für Jahre. Dieses Kapitel erklärt, warum diese Serie das Paket gewechselt hat, und installiert danach Filament.
Warum sich dieses Kapitel geändert hat
Die früheren Fassungen dieses Tutorials setzten auf Voyager. Das ist nicht mehr haltbar.
tcg/voyager ist auf Packagist als aufgegeben markiert. Die letzte Version 1.8.0 stammt vom September 2024 und deklariert Kompatibilität nur bis Laravel 11. In einem Laravel-13-Projekt verweigert Composer schlicht die Installation: Er bleibt zuerst an den Sicherheitshinweisen hängen, die alle Versionen betreffen, und die Laravel-11-Einschränkung ließe die Auflösung ohnehin scheitern.
Das ist die brauchbare Lehre aus der Episode: Ein Tutorial, das auf einem Paket aus der Hand eines einzigen Teams aufbaut, wird an dem Tag falsch, an dem dieses Team aufhört. Die Wahl des Ersatzes muss deshalb den Gesundheitszustand des Projekts genauso abwägen wie seine Funktionen.
Was geprüft wurde
Vier Kandidaten, am 2. September 2026 anhand der öffentlichen Daten von Packagist gemessen:
| Paket | Letzte Version | Laravel 13 | Downloads / Monat |
|---|---|---|---|
tcg/voyager | 1.8.0 (Sept. 2024) | nein | 23.614, aber abandoned |
ilsondev/voyager | 2.2.1 (Juli 2026) | ja | 1 |
orchid/platform | 14.53.0 (März 2026) | ja | 27.227 |
filament/filament | 5.7.8 (Aug. 2026) | ja | 3.324.015 |
ilsondev/voyager ist ein Fork, der funktioniert: Für diese Überarbeitung wurde er auf einem frischen Laravel 13.30.1 installiert, und Dashboard, BREAD-Werkzeug, Mediathek, Menü-Builder und Einstellungen antworten alle korrekt. Aber er kommt auf 12 Downloads und einen Stern, und alle seine Versionen wurden an drei Tagen im Juli 2026 veröffentlicht. Er zieht außerdem intervention/image in Version 2 nach, deren Branch nicht mehr der aktuelle ist. Diesen Fork einem Einsteiger zu empfehlen hieße, genau den Fehler zu wiederholen, der dieses Tutorial zerlegt hat.
Wenn du allerdings eine bestehende Voyager-Anwendung pflegst und zunächst nur auf Laravel 13 kommen willst, ohne alles neu zu schreiben, ist dieser Fork eine anständige Brücke. Behandle ihn als Zwischenschritt, nicht als Ziel.
Die Wahl: Filament
Filament macht aus drei Gründen das Rennen.
- Es verschwindet nicht morgen. 3,3 Millionen Downloads pro Monat, das Hundertfache aller Alternativen zusammen, und wöchentlich neue Versionen.
- Das Back-Office ist Code. Voyager legte die Konfiguration der Masken in der Datenbank ab, in einer Oberfläche zusammengeklickt. Bei Filament ist jede Maske eine PHP-Klasse, die mit dem Rest des Projekts versioniert wird. Sie lässt sich lesen, vergleichen und ausrollen wie jede andere Datei.
- Es ist eine Fähigkeit, die sich auszahlt. Filament ist heute das Standard-Back-Office im Laravel-Ökosystem. Was du hier lernst, findest du in einem echten Projekt wieder.
Zwei kostenpflichtige Alternativen sollte man kennen, nötig sind sie für dieses Tutorial nicht: Nova, die offizielle Lösung des Laravel-Teams, und Backpack.
Filament installieren
Die Erweiterung intl muss vorhanden sein
Filament setzt die PHP-Erweiterung intl voraus. Prüf sie vor der Installation:
php -m | grep intlGibt der Befehl nichts aus, scheitert die Installation an dieser Meldung, die Filament nicht erwähnt und ratlos zurücklässt:
filament/support[...] require ext-intl * -> it is missing from your system.
Install or enable PHP's intl extension.Das erste Kapitel riet genau deshalb schon dazu, sie zu prüfen. Unter Debian oder Ubuntu: sudo apt install php8.4-intl. Unter macOS mit Homebrew ist die Erweiterung bereits da. Unter Windows mit WampServer nimmst du im Menü der PHP-Erweiterungen den Haken bei php_intl weg und setzt ihn wieder. Starte anschließend deinen Server neu.
Das Paket und das Panel
composer require filament/filament
php artisan filament:install --panelsDer zweite Befehl legt app/Providers/Filament/AdminPanelProvider.php an, veröffentlicht die CSS- und JavaScript-Dateien des Panels in public und leert die Caches.
INFO Successfully published assets!
INFO Successfully upgraded!Ein Konto anlegen
php artisan make:filament-userDer Befehl fragt nach Name, E-Mail-Adresse und Passwort und bestätigt dann:
INFO Success! admin@gekkode.test may now log in at http://localhost:8000/admin/login.Ruf http://127.0.0.1:8000/admin auf und melde dich an. Das Dashboard ist leer: völlig normal, es wurde ihm noch nichts anvertraut. Kapitel 6 ergänzt dort die Artikel, die Kategorien und die Tags.
Steuern, wer hineindarf
In der lokalen Umgebung lässt Filament jeden authentifizierten Benutzer hinein. Überall sonst weist es alle mit einem 403 ab, solange das Modell User nicht gesagt hat, wer hineindarf. Das ist eine Absicherung ab Werk, sie überrascht aber: Auf deiner Maschine läuft das Panel, und ab dem Livegang liefert es 403.
Die Regel wird durch das Implementieren des Interface FilamentUser deklariert. Behalten Sie alles, was das mitgelieferte Modell bereits enthält, die Attribute #[Fillable] und #[Hidden] ebenso wie die Methode casts(): Nur das Interface und die Methode canAccessPanel() kommen hinzu.
<?php
namespace App\Models;
use Database\Factories\UserFactory;
use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable implements FilamentUser
{
/** @use HasFactory<UserFactory> */
use HasFactory, Notifiable;
public function canAccessPanel(Panel $panel): bool
{
return str_ends_with($this->email, '@gekkode.test');
}
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}Ersetz die Domain durch deine eigene. Diese Regel ist bewusst simpel: Für ein Lernprojekt reicht sie, für eine öffentliche Website nicht. Ein echtes Projekt stützt sich auf eine Spalte is_admin oder auf ein Rollensystem.
Das Verhalten wird mit zwei Tests geprüft. Der zweite zählt genauso viel wie der erste: In der Testumgebung weist Filament alle ab, solange die Regel nicht existiert, sodass ein Test, der nur die Abweisung prüft, auch ohne sie bestehen würde.
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AdminTest extends TestCase
{
use RefreshDatabase;
public function test_un_email_hors_domaine_est_refuse(): void
{
$user = User::factory()->create(['email' => 'intrus@example.com']);
$this->actingAs($user)->get('/admin')->assertForbidden();
}
public function test_un_email_du_domaine_est_accepte(): void
{
$user = User::factory()->create(['email' => 'admin@gekkode.test']);
$this->actingAs($user)->get('/admin')->assertOk();
}
}Von der Voyager-Fassung dieses Tutorials migrieren
Wenn du dieses Tutorial in seiner Voyager-Fassung durchgearbeitet hast, ändert sich Folgendes.
- Die Voyager-Tabellen verschwinden. Die Installation legte zehn davon an:
data_types,data_rows,menus,menu_items,settings,roles,permissions,permission_role,user_rolesundtranslations. Keine davon wird noch gebraucht. Deine fachlichen Tabellen,posts,categories,tags,post_tag,users, bleiben unverändert: Filament dockt ohne Datenmigration daran an. - Die BREAD-Konfiguration ist verloren, und das ist so gewollt. Was du in Voyager zusammengeklickt hattest, schreibst du einmal in PHP neu, in den Dateien aus Kapitel 6. Das ist eine halbe Stunde Arbeit, danach ist die Konfiguration versioniert.
- Die Funktion
setting()gibt es nicht mehr. Voyager lieferte sie mit, um Titel und Beschreibung der Website zu lesen. Ersetzsetting('site.title')durchconfig('app.name')oder durch deine eigenen Einstellungen. - Der Umweg um den Slug
postsentfällt. Voyager brachte ein eigenes ModellPostmit, weshalb der Slug der Tabelle inblog-postsumbenannt und ein Template des Pakets korrigiert werden musste. Filament schreibt kein Modell vor, der Konflikt verschwindet. - Die Adresse des Back-Office bleibt gleich. Filament installiert sich ebenfalls unter
/admin.
Um Voyager aus einem bestehenden Projekt zu entfernen: composer remove tcg/voyager, dann löschst du seine Tabellen und den Ordner resources/views/vendor/voyager, falls er existiert. Leg vorher ein Backup der Datenbank an.
Was dieses Kapitel nicht behandelt hat
Feingranulare Rollen und Berechtigungen, das Anpassen des Panel-Themes und die Widgets des Dashboards sprengen den Rahmen dieser Serie. Die Filament-Dokumentation deckt sie ab.
Das nächste Kapitel baut die Startseite der öffentlichen Website.