Chapitre 4 sur 9

Tutoriel Laravel 13 #4 : Panneau d’administration

vérifié le 7 septembre 2026 · 7 min

Réponse rapide

Laravel ne fournit pas de back-office. Cette série utilise désormais Filament : composer require filament/filament puis php artisan filament:install --panels. Voyager, employé dans les versions précédentes, est marqué abandonné sur Packagist et ne s’installe plus sur Laravel 13.

À la fin de ce chapitre, vous aurez un back-office Filament installé sur /admin, avec un compte administrateur et une règle d’accès explicite.

Laravel ne fournit pas de back-office. Il faut en choisir un, et ce choix engage le projet pour des années. Ce chapitre explique pourquoi cette série a changé de paquet, puis installe Filament.

Pourquoi ce chapitre a changé

Les versions précédentes de ce tutoriel utilisaient Voyager. Ce n’est plus tenable.

tcg/voyager est marqué comme abandonné sur Packagist. Sa dernière version, la 1.8.0, date de septembre 2024 et déclare une compatibilité qui s’arrête à Laravel 11. Sur un projet Laravel 13, Composer refuse simplement de l’installer : il bloque d’abord sur les avis de sécurité qui visent toutes ses versions, et sa contrainte Laravel 11 ferait de toute façon échouer la résolution.

C’est la leçon utile de l’épisode : un tutoriel qui repose sur un paquet maintenu par une seule équipe devient faux le jour où cette équipe s’arrête. Le choix de remplacement doit donc peser la santé du projet autant que ses fonctionnalités.

Ce qui a été examiné

Quatre pistes, mesurées le 2 septembre 2026 sur les données publiques de Packagist :

Paquet Dernière version Laravel 13 Téléchargements / mois
tcg/voyager 1.8.0 (sept. 2024) non 23 614, mais abandonné
ilsondev/voyager 2.2.1 (juil. 2026) oui 1
orchid/platform 14.53.0 (mars 2026) oui 27 227
filament/filament 5.7.8 (août 2026) oui 3 324 015

ilsondev/voyager est un fork qui fonctionne : il a été installé sur un Laravel 13.30.1 neuf pour cette révision, et le tableau de bord, l’outil BREAD, la médiathèque, le constructeur de menus et les réglages répondent tous correctement. Mais il totalise 12 téléchargements et une étoile, et toutes ses versions ont été publiées en trois jours de juillet 2026. Il tire aussi intervention/image en version 2, dont la branche n’est plus la branche courante. Recommander ce fork à un débutant, ce serait refaire exactement l’erreur qui a cassé ce tutoriel.

Reste que si vous maintenez une application Voyager existante et que vous cherchez d’abord à passer à Laravel 13 sans tout réécrire, ce fork est une passerelle honnête. Traitez-le comme une étape, pas comme une destination.

Le choix : Filament

Filament l’emporte pour trois raisons.

  • Il ne disparaîtra pas demain. 3,3 millions de téléchargements par mois, cent fois l’audience de toutes les alternatives réunies, et des versions publiées chaque semaine.
  • Le back-office est du code. Voyager stockait la configuration des écrans dans la base de données, cliquée dans une interface. Chez Filament, chaque écran est une classe PHP versionnée avec le reste du projet. Elle se relit, se compare et se déploie comme n’importe quel fichier.
  • C’est une compétence qui sert. Filament est aujourd’hui le back-office par défaut de l’écosystème Laravel. Ce que vous apprenez ici se retrouvera dans un vrai projet.

Deux alternatives payantes méritent d’être connues, sans être nécessaires pour ce tutoriel : Nova, la solution officielle de l’équipe Laravel, et Backpack.

Installer Filament

L’extension intl doit être présente

Filament exige l’extension PHP intl. Vérifiez-la avant d’installer :

bash
php -m | grep intl

Si la commande ne renvoie rien, l’installation échouera sur ce message, qui ne mentionne pas Filament et laisse perplexe :

code
filament/support[...] require ext-intl * -> it is missing from your system.
Install or enable PHP's intl extension.

Le premier chapitre conseillait déjà de la vérifier pour cette raison. Sous Debian ou Ubuntu, sudo apt install php8.4-intl. Sous macOS avec Homebrew, l’extension est déjà là. Sous Windows avec WampServer, décochez puis recochez php_intl dans le menu des extensions PHP. Redémarrez ensuite votre serveur.

Le paquet et le panneau

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

La seconde commande crée app/Providers/Filament/AdminPanelProvider.php, publie les fichiers CSS et JavaScript du panneau dans public, et vide les caches.

code
INFO  Successfully published assets!
INFO  Successfully upgraded!

Créer un compte

bash
php artisan make:filament-user

La commande demande un nom, une adresse e-mail et un mot de passe, puis confirme :

code
INFO  Success! admin@gekkode.test may now log in at http://localhost:8000/admin/login.

Rendez-vous sur http://127.0.0.1:8000/admin et connectez-vous. Le tableau de bord est vide : c’est normal, rien ne lui a encore été confié. Le chapitre 6 y ajoutera les articles, les catégories et les étiquettes.

Contrôler qui entre

En environnement local, Filament laisse entrer tout utilisateur authentifié. Partout ailleurs, il refuse tout le monde avec une erreur 403 tant que le modèle User n’a pas dit qui a le droit d’entrer. C’est une sécurité par défaut, mais elle surprend : le panneau marche sur votre machine et renvoie 403 dès la mise en ligne.

La règle se déclare en implémentant l’interface FilamentUser. Gardez tout ce que le modèle livré contient déjà, les attributs #[Fillable] et #[Hidden] comme la méthode casts() : seuls l’interface et la méthode canAccessPanel() s’ajoutent.

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',
        ];
    }
}

Remplacez le domaine par le vôtre. Cette règle est volontairement simpliste : elle suffit à un projet d’apprentissage, pas à un site public. Un vrai projet s’appuie sur une colonne is_admin ou sur un système de rôles.

Le comportement se vérifie par deux tests. Le second compte autant que le premier : en environnement de test, Filament refuse tout le monde tant que la règle n’existe pas, et un test qui ne vérifie que le refus passerait donc même sans elle.

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();
    }
}

Migrer depuis la version Voyager de ce tutoriel

Si vous aviez suivi ce tutoriel dans sa version Voyager, voici ce qui change.

  • Les tables de Voyager disparaissent. L’installation en créait dix : data_types, data_rows, menus, menu_items, settings, roles, permissions, permission_role, user_roles et translations. Aucune ne sert plus. Vos tables métier, posts, categories, tags, post_tag, users, sont conservées telles quelles : Filament se branche dessus sans migration de données.
  • La configuration BREAD est perdue, et c’est voulu. Ce que vous aviez cliqué dans Voyager se réécrit en PHP, une fois, dans les fichiers du chapitre 6. C’est une demi-heure de travail, après quoi la configuration est versionnée.
  • La fonction setting() n’existe plus. Voyager la fournissait pour lire le titre et la description du site. Remplacez setting('site.title') par config('app.name'), ou par vos propres réglages.
  • Le contournement du slug posts devient inutile. Voyager livrait son propre modèle Post, ce qui obligeait à renommer le slug de la table en blog-posts et à corriger un gabarit du paquet. Filament n’impose aucun modèle, le conflit disparaît.
  • L’adresse du back-office ne change pas. Filament s’installe aussi sur /admin.

Pour retirer Voyager d’un projet existant : composer remove tcg/voyager, puis supprimez ses tables et le dossier resources/views/vendor/voyager s’il existe. Faites une sauvegarde de la base avant.

Ce que ce chapitre n’a pas traité

Les rôles et permissions fins, la personnalisation du thème du panneau et les widgets du tableau de bord dépassent le cadre de cette série. La documentation de Filament les couvre.

Le chapitre suivant construit la page d’accueil du site public.

Erreurs fréquentes

ext-intl is missing from your system Filament exige l’extension intl. Le message de composer ne nomme pas Filament et laisse perplexe. Installez php-intl puis relancez l’installation.
Le panneau renvoie 403 en dehors de l’environnement local Filament refuse tout le monde tant que le modèle User n’implémente pas FilamentUser::canAccessPanel(). Le panneau marche en local et casse à la mise en ligne.
Composer refuse d’installer tcg/voyager Le paquet s’arrête à Laravel 11 et est marqué abandonné. Il n’existe pas de version compatible Laravel 13.
Newsletter

Les nouveaux tests, tutoriels et projets, par e-mail.

Tests reproductibles, code versionné, résultats datés. Jamais de spam.