Kapitel 4 von 9

Laravel-13-Tutorial #4: Admin-Panel mit Filament einrichten

geprüft am 7 September 2026 · 6 Min.

Schnelle Antwort

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.

Am Ende dieses Kapitels, hast du ein Filament-Back-Office unter /admin installiert, mit einem Administratorkonto und einer ausdrücklichen Zugriffsregel.

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:

bash
php -m | grep intl

Gibt der Befehl nichts aus, scheitert die Installation an dieser Meldung, die Filament nicht erwähnt und ratlos zurücklässt:

code
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

bash
composer require filament/filament
php artisan filament:install --panels

Der zweite Befehl legt app/Providers/Filament/AdminPanelProvider.php an, veröffentlicht die CSS- und JavaScript-Dateien des Panels in public und leert die Caches.

code
INFO  Successfully published assets!
INFO  Successfully upgraded!

Ein Konto anlegen

bash
php artisan make:filament-user

Der Befehl fragt nach Name, E-Mail-Adresse und Passwort und bestätigt dann:

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

app/Models/User.php
<?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.

tests/Feature/AdminTest.php
<?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_roles und translations. 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. Ersetz setting('site.title') durch config('app.name') oder durch deine eigenen Einstellungen.
  • Der Umweg um den Slug posts entfällt. Voyager brachte ein eigenes Modell Post mit, weshalb der Slug der Tabelle in blog-posts umbenannt 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.

Häufige Fehler

ext-intl is missing from your system Filament setzt die Erweiterung intl voraus. Die Meldung von Composer nennt Filament nicht und lässt ratlos zurück. Installier php-intl und starte die Installation neu.
Das Panel liefert außerhalb der lokalen Umgebung 403 Filament weist alle ab, solange das Modell User nicht FilamentUser::canAccessPanel() implementiert. Lokal läuft das Panel und beim Livegang bricht es.
Composer weigert sich, tcg/voyager zu installieren Das Paket endet bei Laravel 11 und ist als abandoned markiert. Eine mit Laravel 13 kompatible Version existiert nicht.
Newsletter

Neue Tests, Tutorials und Projekte, per E-Mail.

Reproduzierbare Tests, versionierter Code, datierte Ergebnisse. Niemals Spam.