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 gst = useGlobalStates();
  const session = gst.get('session');

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

  return <Outlet />;
};

/**
 * Private routes (home, settings, etc.)
 * Redirects to /login if not authenticated
 */
export const PrivateRoutes = () => {
  const gst = useGlobalStates();
  const session = gst.get('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 qui retourne un objet avec des methodes de navigation :

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

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

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

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

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

      {/* Remplacer l'historique (builder chainable) */}
      <button onClick={() => nav.replace().to('/login')}>
        Déconnexion
      </button>
    </div>
  );
};

Propriétés retournées

Propriété Description
nav.navigate(to, options) Fonction de navigation React Router
nav.params Paramètres de la route (useParams)
nav.searchParams Query string (useSearchParams)
nav.location Objet location courant
nav.history Historique de navigation
nav.replace() Builder chainable : remplacer au lieu de pousser
nav.state(value) Builder chainable : passer un state
nav.to(path) Builder chainable : executer la navigation

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 nav = 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={() => nav.navigate('/')}>Accueil</button>
        <button onClick={() => nav.navigate('/search')}>Recherche</button>
        <button onClick={() => nav.navigate('/profile')}>Profil</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 nav = 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={() => nav.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 gst = useGlobalStates();
  const session = gst.get('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
      • Propriétés retournées
      • 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
    • Synchronisation offline
    • 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 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
      • Chapitre 4 : Synchronisation Offline
    • 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