SmarMaker - Documentation
Docs» 03_front:routage

Routage

Documentation React Router v7

SmartMaker utilise React Router pour gérer la navigation entre les pages de l'application (Single Page Application).

Configuration de base

Créer le Router

// src/components/app/Router/index.jsx

import { BrowserRouter, Routes, Route } from 'react-router-dom';

import { LoginPage } from '../../pages/public/LoginPage';
import { HomePage } from '../../pages/private/HomePage';
import { Error404Page } from '../../pages/errors/Error404Page';

export const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/login" element={<LoginPage />} />
        <Route path="/" element={<HomePage />} />
        <Route path="*" element={<Error404Page />} />
      </Routes>
    </BrowserRouter>
  );
};

Intégrer dans App.jsx

// src/App.jsx

import { Provider } from '@cap-rel/smartcommon';
import { Router } from './components/app/Router';
import { config } from './appConfig';

export const App = () => {
  return (
    <Provider config={config}>
      <Router />
    </Provider>
  );
};

Routes protégées

Guards d'authentification

// src/components/app/Router/Guards/index.jsx

import { Outlet, Navigate } from 'react-router-dom';
import { useGlobalStates } from '@cap-rel/smartcommon';

/**
 * Routes publiques (login, register, etc.)
 * Redirige vers / si déjà connecté
 */
export const PublicRoutes = () => {
  const [session] = useGlobalStates('session');

  if (session) {
    return <Navigate to="/" replace />;
  }

  return <Outlet />;
};

/**
 * Routes privées (home, settings, etc.)
 * Redirige vers /login si non connecté
 */
export const PrivateRoutes = () => {
  const [session] = useGlobalStates('session');

  if (!session) {
    return <Navigate to="/login" replace />;
  }

  return <Outlet />;
};

Utiliser les Guards

// src/components/app/Router/index.jsx

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { PublicRoutes, PrivateRoutes } from './Guards';

// Pages publiques
import { WelcomePage } from '../../pages/public/WelcomePage';
import { LoginPage } from '../../pages/public/LoginPage';

// Pages privées
import { HomePage } from '../../pages/private/HomePage';
import { SettingsPage } from '../../pages/private/SettingsPage';
import { ItemPage } from '../../pages/private/ItemPage';

// Erreurs
import { Error404Page } from '../../pages/errors/Error404Page';

export const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
        {/* Routes publiques */}
        <Route element={<PublicRoutes />}>
          <Route path="/welcome" element={<WelcomePage />} />
          <Route path="/login" element={<LoginPage />} />
        </Route>

        {/* Routes privées */}
        <Route element={<PrivateRoutes />}>
          <Route path="/" element={<HomePage />} />
          <Route path="/settings" element={<SettingsPage />} />
          <Route path="/items/:id" element={<ItemPage />} />
        </Route>

        {/* Fallback 404 */}
        <Route path="*" element={<Error404Page />} />
      </Routes>
    </BrowserRouter>
  );
};

Navigation

Hook useNavigation

SmartCommon expose useNavigation pour naviguer entre les pages :

import { useNavigation } from '@cap-rel/smartcommon';

const MyComponent = () => {
  const navigate = useNavigation();

  return (
    <div>
      {/* Navigation simple */}
      <button onClick={() => navigate('/')}>Accueil</button>
      <button onClick={() => navigate('/settings')}>Paramètres</button>

      {/* Avec paramètres */}
      <button onClick={() => navigate(`/items/${itemId}`)}>Voir l'item</button>

      {/* Retour en arrière */}
      <button onClick={() => navigate(-1)}>Retour</button>

      {/* Remplacer l'historique (pas de retour possible) */}
      <button onClick={() => navigate('/login', { replace: true })}>
        Déconnexion
      </button>
    </div>
  );
};

Composant Link

Pour les liens simples, utilisez le composant Link :

import { Link } from 'react-router-dom';

const Navigation = () => {
  return (
    <nav>
      <Link to="/">Accueil</Link>
      <Link to="/settings">Paramètres</Link>
      <Link to="/items/123">Item 123</Link>
    </nav>
  );
};

Paramètres de route

Paramètres dynamiques

// Route avec paramètre :id
<Route path="/items/:id" element={<ItemPage />} />

// Récupérer le paramètre
import { useParams } from 'react-router-dom';

const ItemPage = () => {
  const { id } = useParams();  // id = "123" pour /items/123

  return <div>Item #{id}</div>;
};

Paramètres multiples

// Route avec plusieurs paramètres
<Route path="/users/:userId/posts/:postId" element={<PostPage />} />

const PostPage = () => {
  const { userId, postId } = useParams();
  // ...
};

Query strings

import { useSearchParams } from 'react-router-dom';

const SearchPage = () => {
  const [searchParams, setSearchParams] = useSearchParams();

  // Lire : /search?q=test&page=2
  const query = searchParams.get('q');     // "test"
  const page = searchParams.get('page');   // "2"

  // Modifier
  const handleSearch = (newQuery) => {
    setSearchParams({ q: newQuery, page: '1' });
  };

  return (
    <input
      value={query || ''}
      onChange={(e) => handleSearch(e.target.value)}
    />
  );
};

Routes imbriquées

Layout partagé

// src/components/app/Router/index.jsx

<Routes>
  <Route element={<PrivateRoutes />}>
    {/* Layout avec navigation bottom */}
    <Route element={<MainLayout />}>
      <Route path="/" element={<HomePage />} />
      <Route path="/search" element={<SearchPage />} />
      <Route path="/profile" element={<ProfilePage />} />
    </Route>

    {/* Pages sans navigation bottom */}
    <Route path="/items/:id" element={<ItemPage />} />
    <Route path="/settings" element={<SettingsPage />} />
  </Route>
</Routes>

Composant Layout

// src/components/layouts/MainLayout/index.jsx

import { Outlet } from 'react-router-dom';
import { useNavigation } from '@cap-rel/smartcommon';

export const MainLayout = () => {
  const navigate = useNavigation();

  return (
    <div className="min-h-screen flex flex-col">
      {/* Contenu de la page (Outlet = enfant de la route) */}
      <main className="flex-1">
        <Outlet />
      </main>

      {/* Navigation fixe en bas */}
      <nav className="bg-white shadow-lg p-2 flex justify-around">
        <button onClick={() => navigate('/')}>🏠</button>
        <button onClick={() => navigate('/search')}>🔍</button>
        <button onClick={() => navigate('/profile')}>👤</button>
      </nav>
    </div>
  );
};

Animations de transition

Configuration dans appConfig

// appConfig.js

export const config = {
  pages: {
    // Depuis la home
    "/": {
      "/settings": "slideLeft",   // Home → Settings : slide vers la gauche
      "/items/*": "slideLeft",    // Home → Item : slide vers la gauche
      "*": "fade",                // Autres : fade
    },
    // Depuis settings
    "/settings": {
      "/": "slideRight",          // Settings → Home : slide vers la droite
    },
    // Par défaut
    "*": "fade",
  },
};

Animations disponibles

Animation Description
fade Fondu enchaîné
slideLeft Glissement vers la gauche
slideRight Glissement vers la droite
zoom Zoom avant/arrière

Voir Animations pour plus de détails.

Gestion d'erreurs

Page 404

// src/components/pages/errors/Error404Page/index.jsx

import { useNavigation } from '@cap-rel/smartcommon';

export const Error404Page = () => {
  const navigate = useNavigation();

  return (
    <div className="min-h-screen flex flex-col items-center justify-center p-4">
      <h1 className="text-6xl font-bold text-gray-300 mb-4">404</h1>
      <p className="text-gray-600 mb-8">Page non trouvée</p>
      <button
        onClick={() => navigate('/')}
        className="bg-primary text-white px-6 py-3 rounded-lg"
      >
        Retour à l'accueil
      </button>
    </div>
  );
};

Redirection conditionnelle

import { Navigate, useLocation } from 'react-router-dom';
import { useGlobalStates } from '@cap-rel/smartcommon';

const RequireAuth = ({ children }) => {
  const [session] = useGlobalStates('session');
  const location = useLocation();

  if (!session) {
    // Sauvegarder l'URL pour rediriger après login
    return <Navigate to="/login" state={{ from: location }} replace />;
  }

  return children;
};

Bonnes pratiques

Structure des routes

  • Groupez les routes par type (public, private, errors)
  • Utilisez des guards pour la protection
  • Placez le fallback * en dernier

Navigation

  • Préférez useNavigation de SmartCommon
  • Utilisez replace: true pour les redirections (login, logout)
  • Évitez les chemins hardcodés, utilisez des constantes

Performance

  • Lazy loading pour les grosses pages
  • Animations légères sur mobile
  • Pré-chargement des données critiques

Voir aussi

  • Animations - Transitions de pages
  • Composants et pages - Structure des pages
  • Hooks - useNavigation
  • Configuration - Options du Provider
Previous Next

Made with ❤ by CAP-REL · SmartMaker · GNU AGPL v3+
Code source · Faire un don
SmarMaker - Documentation
Traductions de cette page:
  • Français
  • Deutsch
  • English
  • Español
  • Italiano
  • Nederlands

Table of Contents

Table des matières

  • Routage
    • Configuration de base
      • Créer le Router
      • Intégrer dans App.jsx
    • Routes protégées
      • Guards d'authentification
      • Utiliser les Guards
    • Navigation
      • Hook useNavigation
      • Composant Link
    • Paramètres de route
      • Paramètres dynamiques
      • Paramètres multiples
      • Query strings
    • Routes imbriquées
      • Layout partagé
      • Composant Layout
    • Animations de transition
      • Configuration dans appConfig
      • Animations disponibles
    • Gestion d'erreurs
      • Page 404
      • Redirection conditionnelle
    • Bonnes pratiques
      • Structure des routes
      • Navigation
      • Performance
    • Voir aussi
  • SmartAuth
  • SmartMaker - Back (PHP)
    • Mapping Dolibarr - React
  • SmartMaker - Front (React)
    • Animations de pages
    • Architecture
    • Astuces
    • Calendar
    • Composants et pages
    • Configuration du Provider
    • Debug et Logs
    • Hooks SmartCommon
    • PWA (Progressive Web App)
    • Requêtes API
    • Routage
    • SmartCommon
    • Stockage de données
    • Thèmes
    • Traductions
  • HowTo - Pas à pas - Votre première application
    • Développement PHP (back)
    • Développement React (front)
    • Première étape : Module Builder Dolibarr
    • SmartAuth
    • SmartBoot : Un "squelette" quasiment prêt à l'emploi
  • Formation SmartMaker
    • Module 1 : Fondamentaux JavaScript ES6+
      • Chapitre 1 : Variables et Scope
      • Chapitre 2 : Fonctions
      • Chapitre 3 : Programmation Asynchrone
      • Chapitre 4 : Modules ES6
    • Module 2 : Introduction à React
      • Chapitre 1 : Philosophie React
      • Chapitre 2 : JSX
      • Chapitre 3 : Composants
    • Module 3 : Hooks React Fondamentaux
      • Chapitre 1 : useState
      • Chapitre 2 : useEffect
      • Chapitre 3 : useRef
      • Chapitre 4 : useContext
    • Module 4 : React Avancé
      • Chapitre 1 : useCallback et useMemo
      • Chapitre 2 : Custom Hooks
      • Chapitre 3 : Redux et Redux Toolkit
    • Module 5 : Architecture SmartMaker
      • Chapitre 1 : Structure du projet
      • Chapitre 2 : Configuration
      • Chapitre 3 : Flux de données
    • Module 6 : SmartCommon - Composants
      • Chapitre 1 : Mise en page
      • Chapitre 2 : Navigation
      • Chapitre 3 : Formulaires
      • Chapitre 4 : Affichage
    • Module 7 : SmartCommon - Hooks
      • Chapitre 1 : useApi
      • Chapitre 2 : Gestion d'état
      • Chapitre 3 : Hooks utilitaires
    • Module 8 : Backend API (PHP)
      • Chapitre 1 : Routage
      • Chapitre 2 : Controllers
      • Chapitre 3 : Mappers
      • Extrafields et formulaires dynamiques
    • Module 9 : Intégration complète
      • Chapitre 1 : Backend
      • Chapitre 2 : Frontend
      • Chapitre 3 : Déploiement
    • Module 10 : Fonctionnalités avancées
      • Chapitre 1 : Mode offline
      • Chapitre 2 : Internationalisation (i18n)
      • Chapitre 3 : Autres fonctionnalités
    • Module 11 : Bonnes pratiques
  • Démonstration
  • Start
  • Composants et pages
  • Afficher le texte source
  • Anciennes révisions
  • Liens de retour
  • Haut de page