SmarMaker - Documentation
Docs» front» 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

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


  • SmartMaker
    • SmartAuth
    • Back (PHP)
      • Mapping Dolibarr
    • Front (React)
      • Configuration
      • SmartCommon
      • Hooks
      • Architecture
      • Composants et pages
      • Routage
      • Requêtes Api
      • Stockage de données
      • Animations
      • Traductions
      • Thèmes
      • PWA
      • Debug
      • Astuces
    • HowTo first app
  • Formations
  • Démonstration
  • Afficher le texte source
  • Anciennes révisions
  • Liens de retour
  • Haut de page
  • S'identifier
front/routage.txt · Dernière modification : 2026/01/11 22:52 de 127.0.0.1