Apprends à offrir une UX admin SaaS avec React Router 7: ErrorBoundary dédié, routes catch-all, sidebar active et dashboard synthétique. Level up dev.
avec React Router 7
Posez vos questions 24/7 à notre IA experte en React Router 7
Validez vos acquis avec des quiz personnalisés et un feedback instantané
Jusqu’ici l’admin tombait :
Dans cette itération nous :
ErrorBoundary
dédié au layout admin ;ErrorBoundary
spécifique au back-officePourquoi ? Conserver la sidebar même lorsqu’une route interne lève une erreur.
1export function ErrorBoundary() {2return (3<SidebarProvider>4<AdminSidebar /> // ✅ sidebar toujours visible5<SidebarInset>6<header className="flex h-16 items-center gap-2 border-b px-4">7<SidebarTrigger className="-ml-1" />8<h1 className="text-xl font-semibold text-destructive">9Administration – Erreur10</h1>11</header>12<div className="flex flex-1 flex-col gap-4 p-4">13<GeneralErrorBoundary14defaultStatusHandler={({ error }) => (15<AdminErrorCard error={error} /> // composant décrit plus bas16)}17/* statusHandlers 404, 403, fallback … */18/>19</div>20</SidebarInset>21</SidebarProvider>22)23}
GeneralErrorBoundary
pour garder la navigation latérale.statusHandlers
personnalisent le rendu (404 → liens utiles, 403 → message
d’accès refusé, etc.).Objectif : intercepter toute URL inconnue sous /admin/*
et afficher
un message contextuel.
1export async function loader({ request }: Route.LoaderArgs) {2await requireAdmin(request) // sécurité = encore obligatoire3throw data("Page d'administration introuvable", { status: 404 })4}56export function ErrorBoundary() {7return <AdminNotFound /> // carte 404 illustrée8}
$.tsx
(« dollar » dans le file-based routing) = catch-all.AdminNotFound
(liens rapides vers produits, users…).Même principe côté front pour conserver <Navbar />
et <Footer />
en cas
d’erreur :
1export function ErrorBoundary() {2return <PublicNotFound /> // 404 full-width + CTA3}
L’ancienne arborescence :
1/admin/users – Users (admin)2/admin/customers – Customers (doublon)
Action réalisée :
customers+
;users+/index.tsx
en users+/index.tsx
(mais affichant
désormais la liste clients) ;users+/_layout
) a été supprimé ; on ouvre
la page détail dans un nouvel onglet pour un écran « plein » plus lisible.Effet immédiat : moins de redirections, URL plus courtes :
/admin/users/:userId
.
1const isActive = location.pathname.startsWith(link.to)2…3<SidebarMenuButton asChild isActive={isActive}>4<Link to={link.to}>5<IconComponent className="size-4" />6<span>{link.label}</span>7</Link>8</SidebarMenuButton>
startsWith
couvre aussi les routes imbriquées
(/admin/users/123
active /admin/users
).1export async function loader({ request }) {2await requireAdmin(request)3const stats = await getDashboardStats() // Prisma + agrégations4return { stats }5}
1<div className="grid gap-4 md:grid-cols-4">2<KpiCard title="Total utilisateurs" icon={Users} value={stats.totals.users} />3<KpiCard title="Total produits" icon={Package} value={stats.totals.products} />4<KpiCard title="Total commandes" icon={ShoppingCart} value={stats.totals.orders} />5<KpiCard title="Chiffre d'affaires" icon={Euro} value={`${stats.totals.revenue.toLocaleString('fr-FR')}€`} />6</div>
getDashboardStats()
calcule :
totals.users
, products
, orders
, revenue
;ordersByStatus
(PENDING, PAID, FULFILLED) ;recentOrders
(5 dernières) ;recentUsers
.1<SidebarMenuItem>2<SidebarMenuButton onClick={handleSignOut} className="text-red-600">3<LogOut className="size-4" />4<span>Déconnexion</span>5</SidebarMenuButton>6</SidebarMenuItem>
handleSignOut
appelle signOut()
fourni par Better Auth, puis redirige vers /
.
1git checkout -b 7-15-amelioration-experience-admin2git add .3git commit -m "feat(admin): UX améliorée (ErrorBoundary, 404, sidebar active, dashboard)"4git push -u origin 7-15-amelioration-experience-admin
Ta branche est prête pour la PR – la CI passera sans toucher au backend 🚀
Quelle est la principale différence entre les composants client et serveur dans React ?
Quelle technique est recommandée pour éviter les rendus inutiles dans React ?
Quel hook permet de gérer les effets de bord dans un composant React ?
Comment implémenter la gestion des erreurs pour les requêtes API dans React ?
Quelle est la meilleure pratique pour déployer une application React en production ?