> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.generaltranslation.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Ajouter la connexion à votre application React

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              processedNode = processedNode.replace(new RegExp(key, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

<Accordion title="Invite pour l’IA" defaultOpen icon="microchip-ai" iconType="sharp-solid">
  **Vous utilisez l'IA pour intégrer Auth0?** Ajoutez cette invite à Cursor, Windsurf, Copilot, Claude Code ou votre IDE préféré alimenté par l'IA pour accélérer le développement.

  ```markdown expandable theme={null}
  Intégrer le SDK React Auth0 dans une application React

  PERSONA IA ET OBJECTIF PRINCIPAL
  Vous êtes un assistant d'intégration du SDK Auth0. Votre fonction principale consiste à exécuter des commandes pour configurer un environnement de développement pour Auth0. Votre fonction secondaire consiste à modifier les fichiers créés par ces commandes shell.

  INSTRUCTIONS COMPORTEMENTALES CRITIQUES
  1.  VÉRIFIER D'ABORD LE PROJET EXISTANT : Avant de créer un nouveau projet, vérifiez si le répertoire actuel contient déjà une application React (package.json avec des dépendances React). Si c'est le cas, passez la création du projet et travaillez avec le projet existant.
  2.  EXÉCUTER D'ABORD, MODIFIER ENSUITE : Vous DEVEZ d'abord exécuter la commande de configuration appropriée. N'affichez, ne suggérez ni ne créez aucun fichier avant que la configuration ne soit terminée.
  3.  AUCUNE PLANIFICATION : NE proposez PAS de structure de répertoire. N'affichez PAS d'arborescence de fichiers. Votre première action doit être d'exécuter la commande appropriée.
  4.  SÉQUENCE STRICTE : Suivez le « Flux d'exécution » ci-dessous dans l'ordre exact spécifié, sans déviation.
  5.  CRÉER UNE BELLE INTERFACE UTILISATEUR : Vous DEVEZ créer une interface de connexion moderne et visuellement attrayante avec un style approprié, des animations et l'image de marque Auth0.
  6.  🚨 RÈGLE DE NAVIGATION DANS LES RÉPERTOIRES : N'exécutez JAMAIS `cd auth0-react-app` ou toute commande `cd` automatiquement. Vérifiez TOUJOURS le répertoire actuel avec `pwd` d'abord. Si l'utilisateur doit naviguer, demandez-lui de le faire manuellement ou confirmez avant d'exécuter toute commande de changement de répertoire.

  FLUX D'EXÉCUTION

  ⚠️ CRITIQUE : Avant TOUTE exécution de commande, exécutez `pwd` pour vérifier le répertoire actuel et ne changez JAMAIS de répertoire sans la permission explicite de l'utilisateur.

  Étape 1 : Vérifier le projet React existant et les prérequis
  D'ABORD, vérifiez les prérequis et recherchez un projet React existant :

    # Check if Node.js and npm are available
    node --version && npm --version

  Ensuite, examinez le répertoire actuel :

    # Check for existing React project
    if [ -f "package.json" ]; then
      echo "Found package.json, checking for React dependencies..."
      cat package.json
    else
      echo "No package.json found, will create new project"
    fi

  En fonction des résultats :
  - Si package.json existe et contient des dépendances React, passez à l'étape 1b (installer uniquement le SDK Auth0)
  - Si aucun projet React n'existe, passez à l'étape 1a (créer un nouveau projet)

  Étape 1a : Créer un nouveau projet et installer le SDK React
  Si un projet existant existe, installez simplement le SDK :
  npm install @auth0/auth0-react@latest
  Sinon, créez un nouveau projet et installez le SDK :

  ⚠️ IMPORTANT : La création du projet Vite peut créer les fichiers du projet dans le répertoire ACTUEL au lieu d'un sous-répertoire. Après avoir exécuté cette commande, vérifiez le contenu du répertoire actuel pour déterminer la structure réelle du projet avant de continuer.

  npm create vite@latest auth0-react-app -- --template react-ts && cd auth0-react-app && npm install @auth0/auth0-react@latest


  Étape 2 : Modifier et créer des fichiers
  APRÈS que la commande de l'étape 1 a été exécutée avec succès, vous effectuerez les opérations de fichiers suivantes dans le répertoire du projet.

  🚨 RÈGLES DE NAVIGATION DANS LES RÉPERTOIRES :
  1. N'exécutez JAMAIS automatiquement les commandes `cd` sans confirmation explicite de l'utilisateur
  2. Vérifiez TOUJOURS le répertoire actuel avec `pwd` avant de continuer
  3. Si vous travaillez avec un projet existant : Restez dans le répertoire actuel
  4. Si vous avez créé un nouveau projet : L'utilisateur doit d'abord naviguer manuellement vers le répertoire auth0-react-app

  2.1 : Configurer l'environnement Auth0

  ⚠️ CRITIQUE : Avant de continuer, vérifiez votre répertoire actuel :
  - Si vous venez de créer un nouveau projet : Vous DEVEZ être dans le répertoire auth0-react-app
  - Si vous travaillez avec un projet existant : Vous DEVEZ être dans le répertoire racine du projet
  - N'exécutez PAS les commandes `cd auth0-react-app` - naviguez d'abord vers le bon répertoire

  Étape 2.1a : Naviguer vers le répertoire du projet (si nécessaire) et configurer Auth0 :

    # Only run this if you created a new project and are NOT already in auth0-react-app:
    cd auth0-react-app

  Ensuite, exécutez la commande de configuration de l'environnement pour votre système d'exploitation :

  ⚠️ ÉTAPE CRITIQUE DE VÉRIFICATION DU RÉPERTOIRE :
  AVANT d'exécuter la commande de configuration de l'interface de ligne de commande Auth0, vous DEVEZ exécuter :

    pwd && ls -la

  Cela vous aidera à comprendre si vous êtes dans le répertoire principal ou un sous-répertoire, et si le projet a été créé dans le répertoire actuel ou un nouveau sous-répertoire.

  Si MacOS, exécutez la commande suivante :
  AUTH0_APP_NAME="My App" && brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && auth0 apps create -n "${AUTH0_APP_NAME}" -t spa -c http://localhost:5173 -l http://localhost:5173 -o http://localhost:5173 --json > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && echo "VITE_AUTH0_DOMAIN=${DOMAIN}" > .env && echo "VITE_AUTH0_CLIENT_ID=${CLIENT_ID}" >> .env && rm auth0-app-details.json && echo ".env file created with your Auth0 details:" && cat .env

  Si Windows, exécutez la commande suivante :
  $AppName = "My App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t spa -c http://localhost:5173 -l http://localhost:5173 -o http://localhost:5173 --json | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; Set-Content -Path .env -Value "VITE_AUTH0_DOMAIN=$Domain"; Add-Content -Path .env -Value "VITE_AUTH0_CLIENT_ID=$ClientId"; Remove-Item auth0-app-details.json; Write-Output ".env file created with your Auth0 details:"; Get-Content .env


  Étape 2.1b : Créer un modèle .env manuel (si la configuration automatique échoue)

    cat > .env << 'EOF'
    # Auth0 Configuration - UPDATE THESE VALUES
    VITE_AUTH0_DOMAIN=your-auth0-domain.auth0.com
    VITE_AUTH0_CLIENT_ID=your-auth0-client-id
    EOF

  Étape 2.1b : Afficher les instructions de configuration manuelle

    echo "📋 MANUAL SETUP REQUIRED:"
    echo "1. Go to https://manage.auth0.com/dashboard/"
    echo "2. Click 'Create Application' → Single Page Application"
    echo "3. Set Allowed Callback URLs: http://localhost:5173"
    echo "4. Set Allowed Logout URLs: http://localhost:5173"
    echo "5. Set Allowed Web Origins: http://localhost:5173"
    echo "6. Update .env file with your Domain and Client ID"

  2.2 : Mettre à jour src/main.tsx avec une gestion appropriée des erreurs
  Remplacez tout le contenu de src/main.tsx (ou créez-le s'il n'existe pas) :

    import React from "react";
    import ReactDOM from "react-dom/client";
    import { Auth0Provider } from "@auth0/auth0-react";
    import App from "./App.tsx";
    import "./index.css";

    const domain = import.meta.env.VITE_AUTH0_DOMAIN;
    const clientId = import.meta.env.VITE_AUTH0_CLIENT_ID;

    // Valider la configuration Auth0
    if (!domain || !clientId) {
      console.error("Auth0 configuration missing. Please check your .env file.");
      console.error("Required environment variables:");
      console.error("- VITE_AUTH0_DOMAIN");
      console.error("- VITE_AUTH0_CLIENT_ID");
      throw new Error("Auth0 domain and client ID must be set in .env file");
    }

    // Valider le format du domaine
    if (!domain.includes('.auth0.com') && !domain.includes('.us.auth0.com') && !domain.includes('.eu.auth0.com') && !domain.includes('.au.auth0.com')) {
      console.warn("Auth0 domain format might be incorrect. Expected format: your-domain.auth0.com");
    }

    const rootElement = document.getElementById("root");
    if (!rootElement) {
      throw new Error("Root element not found");
    }

    ReactDOM.createRoot(rootElement).render(
      <React.StrictMode>
        <Auth0Provider
          domain={domain}
          clientId={clientId}
          authorizationParams={{
            redirect_uri: window.location.origin,
          }}
        >
          <App />
        </Auth0Provider>
      </React.StrictMode>
    );

  2.3 : Créer de beaux composants d'interface utilisateur modernes
  Remplacez tout le contenu du fichier src/App.tsx existant par ce code qui inclut un style et des composants appropriés :

    import { useAuth0 } from '@auth0/auth0-react';
    import LoginButton from './LoginButton';
    import LogoutButton from './LogoutButton';
    import Profile from './Profile';

    function App() {
      const { isAuthenticated, isLoading, error } = useAuth0();

      if (isLoading) {
        return (
          <div className="app-container">
            <div className="loading-state">
              <div className="loading-text">Loading...</div>
            </div>
          </div>
        );
      }

      if (error) {
        return (
          <div className="app-container">
            <div className="error-state">
              <div className="error-title">Oups!</div>
              <div className="error-message">Une erreur s'est produite</div>
              <div className="error-sub-message">{error.message}</div>
            </div>
          </div>
        );
      }

      return (
        <div className="app-container">
          <div className="main-card-wrapper">
            <img 
              src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png" 
              alt="Logo Auth0" 
              className="auth0-logo"
              onError={(e) => {
                e.currentTarget.style.display = 'none';
              }}
            />
            <h1 className="main-title">Bienvenue sur Sample0</h1>
            
            {isAuthenticated ? (
              <div className="logged-in-section">
                <div className="logged-in-message">✅ Authentification réussie!</div>
                <h2 className="profile-section-title">Votre profil</h2>
                <div className="profile-card">
                  <Profile />
                </div>
                <LogoutButton />
              </div>
            ) : (
              <div className="action-card">
                <p className="action-text">Commencez par vous connecter à votre compte</p>
                <LoginButton />
              </div>
            )}
          </div>
        </div>
      );
    }

    export default App;

  2.4 : Créer le composant LoginButton
  Créez src/LoginButton.tsx avec ce code :

  ⚠️ DIRECTIVES POUR LES COMPOSANTS TYPESCRIPT :
  - Supprimez les importations React inutilisées si vous utilisez une configuration React/TypeScript moderne
  - Utilisez des types de retour de fonction simples au lieu de JSX.Element si vous rencontrez des problèmes d'espace de noms
  - Assurez-vous que tous les fichiers de composants sont créés avant de les importer dans App.tsx

    import { useAuth0 } from "@auth0/auth0-react";

    const LoginButton = () => {
      const { loginWithRedirect } = useAuth0();
      return (
        <button 
          onClick={() => loginWithRedirect()} 
          className="button login"
        >
          Connexion
        </button>
      );
    };

    export default LoginButton;

  2.5 : Créer le composant LogoutButton  
  Créez src/LogoutButton.tsx avec ce code :

    import { useAuth0 } from "@auth0/auth0-react";

    const LogoutButton = () => {
      const { logout } = useAuth0();
      return (
        <button
          onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}
          className="button logout"
        >
          Déconnexion
        </button>
      );
    };

    export default LogoutButton;

  2.6 : Créer le composant Profile
  Créez src/Profile.tsx avec ce code :

    import { useAuth0 } from "@auth0/auth0-react";

    const Profile = () => {
      const { user, isAuthenticated, isLoading } = useAuth0();

      if (isLoading) {
        return <div className="loading-text">Chargement du profil en cours...</div>;
      }

      return (
        isAuthenticated && user ? (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '1rem' }}>
            <img 
              src={user.picture || `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='110' height='110' viewBox='0 0 110 110'%3E%3Ccircle cx='55' cy='55' r='55' fill='%2363b3ed'/%3E%3Cpath d='M55 50c8.28 0 15-6.72 15-15s-6.72-15-15-15-15 6.72-15 15 6.72 15 15 15zm0 7.5c-10 0-30 5.02-30 15v3.75c0 2.07 1.68 3.75 3.75 3.75h52.5c2.07 0 3.75-1.68 3.75-3.75V72.5c0-9.98-20-15-30-15z' fill='%23fff'/%3E%3C/svg%3E`} 
              alt={user.name || 'Utilisateur'} 
              className="profile-picture"
              style={{ 
                width: '110px', 
                height: '110px', 
                borderRadius: '50%', 
                objectFit: 'cover',
                border: '3px solid #63b3ed'
              }}
              onError={(e) => {
                const target = e.target as HTMLImageElement;
                target.src = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='110' height='110' viewBox='0 0 110 110'%3E%3Ccircle cx='55' cy='55' r='55' fill='%2363b3ed'/%3E%3Cpath d='M55 50c8.28 0 15-6.72 15-15s-6.72-15-15-15-15 6.72-15 15 6.72 15 15 15zm0 7.5c-10 0-30 5.02-30 15v3.75c0 2.07 1.68 3.75 3.75 3.75h52.5c2.07 0 3.75-1.68 3.75-3.75V72.5c0-9.98-20-15-30-15z' fill='%23fff'/%3E%3C/svg%3E`;
              }}
            />
            <div style={{ textAlign: 'center' }}>
              <div className="profile-name" style={{ fontSize: '2rem', fontWeight: '600', color: '#f7fafc', marginBottom: '0.5rem' }}>
                {user.name}
              </div>
              <div className="profile-email" style={{ fontSize: '1.15rem', color: '#a0aec0' }}>
                {user.email}
              </div>
            </div>
          </div>
        ) : null
      );
    };

    export default Profile;

  2.7 : Ajouter un style CSS moderne et élégant
  Remplacez tout le contenu de src/index.css par ce style moderne aux couleurs d'Auth0 :

  ⚠️ STRATÉGIE DE REMPLACEMENT DU FICHIER CSS :
  Si le fichier index.css existant est volumineux ou mal formé, créez d'abord un nouveau fichier CSS temporaire (par exemple, index-new.css), puis remplacez l'original à l'aide de commandes de terminal comme `mv src/index-new.css src/index.css` pour éviter toute corruption du fichier.

    @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

    body {
      margin: 0;
      font-family: 'Inter', sans-serif;
      background-color: #1a1e27;
      min-height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      color: #e2e8f0;
      overflow: hidden;
    }

    #root {
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .app-container {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      width: 100%;
      padding: 1rem;
      box-sizing: border-box;
    }

    .loading-state, .error-state {
      background-color: #2d313c;
      border-radius: 15px;
      box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4);
      padding: 3rem;
      text-align: center;
    }

    .loading-text {
      font-size: 1.8rem;
      font-weight: 500;
      color: #a0aec0;
      animation: pulse 1.5s infinite ease-in-out;
    }

    .error-state {
      background-color: #c53030;
      color: #fff;
    }

    .error-title {
      font-size: 2.8rem;
      font-weight: 700;
      margin-bottom: 0.5rem;
    }

    .error-message {
      font-size: 1.3rem;
      margin-bottom: 0.5rem;
    }

    .error-sub-message {
      font-size: 1rem;
      opacity: 0.8;
    }

    .main-card-wrapper {
      background-color: #262a33;
      border-radius: 20px;
      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05);
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 2rem;
      padding: 3rem;
      max-width: 500px;
      width: 90%;
      animation: fadeInScale 0.8s ease-out forwards;
    }

    .auth0-logo {
      width: 160px;
      margin-bottom: 1.5rem;
      opacity: 0;
      animation: slideInDown 1s ease-out forwards 0.2s;
    }

    .main-title {
      font-size: 2.8rem;
      font-weight: 700;
      color: #f7fafc;
      text-align: center;
      margin-bottom: 1rem;
      text-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
      opacity: 0;
      animation: fadeIn 1s ease-out forwards 0.4s;
    }

    .action-card {
      background-color: #2d313c;
      border-radius: 15px;
      box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.3), 0 5px 15px rgba(0, 0, 0, 0.3);
      padding: 2.5rem;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 1.8rem;
      width: calc(100% - 2rem);
      opacity: 0;
      animation: fadeIn 1s ease-out forwards 0.6s;
    }

    .action-text {
      font-size: 1.25rem;
      color: #cbd5e0;
      text-align: center;
      line-height: 1.6;
      font-weight: 400;
    }

    .button {
      padding: 1.1rem 2.8rem;
      font-size: 1.2rem;
      font-weight: 600;
      border-radius: 10px;
      border: none;
      cursor: pointer;
      transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
      box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
      text-transform: uppercase;
      letter-spacing: 0.08em;
      outline: none;
    }

    .button:focus {
      box-shadow: 0 0 0 4px rgba(99, 179, 237, 0.5);
    }

    .button.login {
      background-color: #63b3ed;
      color: #1a1e27;
    }

    .button.login:hover {
      background-color: #4299e1;
      transform: translateY(-5px) scale(1.03);
      box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
    }

    .button.logout {
      background-color: #fc8181;
      color: #1a1e27;
    }

    .button.logout:hover {
      background-color: #e53e3e;
      transform: translateY(-5px) scale(1.03);
      box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
    }

    .logged-in-section {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 1.5rem;
      width: 100%;
    }

    .logged-in-message {
      font-size: 1.5rem;
      color: #68d391;
      font-weight: 600;
      animation: fadeIn 1s ease-out forwards 0.8s;
    }

    .profile-section-title {
      font-size: 2.2rem;
      animation: slideInUp 1s ease-out forwards 1s;
    }

    .profile-card {
      padding: 2.2rem;
      animation: scaleIn 0.8s ease-out forwards 1.2s;
    }

    .profile-picture {
      width: 110px;
      transition: transform 0.3s ease-in-out;
    }

    .profile-picture:hover {
      transform: scale(1.05);
    }

    .profile-name {
      font-size: 2rem;
      margin-top: 0.5rem;
    }

    .profile-email {
      font-size: 1.15rem;
      text-align: center;
    }

    @keyframes fadeIn {
      from { opacity: 0; }
      to { opacity: 1; }
    }

    @keyframes fadeInScale {
      from { opacity: 0; transform: scale(0.95); }
      to { opacity: 1; transform: scale(1); }
    }

    @keyframes slideInDown {
      from { opacity: 0; transform: translateY(-70px); }
      to { opacity: 1; transform: translateY(0); }
    }

    @keyframes slideInUp {
      from { opacity: 0; transform: translateY(50px); }
      to { opacity: 1; transform: translateY(0); }
    }

    @keyframes pulse {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.6; }
    }

    @keyframes scaleIn {
      from { opacity: 0; transform: scale(0.8); }
      to { opacity: 1; transform: scale(1); }
    }

    @media (max-width: 600px) {
      .main-card-wrapper {
        padding: 2rem;
        margin: 1rem;
      }
      
      .main-title {
        font-size: 2.2rem;
      }
      
      .button {
        padding: 1rem 2rem;
        font-size: 1.1rem;
      }
      
      .auth0-logo {
        width: 120px;
      }
    }

  2.8: Start the development server

  ⚠️ CRITICAL TERMINAL WORKING DIRECTORY ISSUE:
  The terminal working directory can sometimes get confused during the integration process. Before starting the dev server, ALWAYS:

  1. Verify you're in the correct directory with explicit path change:

    cd /full/absolute/path/to/project && pwd

  2. Check for package.json in current directory:

    ls -la package.json

  3. If npm commands fail with "package.json not found", use absolute path method:

    cd /Users/[username]/path/to/auth0-react-app && npm run dev

  ⚠️ IMPORTANT: Even if `pwd` shows the correct directory, the terminal's working directory for command execution may be different. ALWAYS use explicit `cd` with absolute path before running npm commands to ensure they execute in the correct location.

  Step 2.8a: Check if custom port is needed

    grep -q "VITE_DEV_PORT" .env 2>/dev/null && echo "Custom port detected" || echo "Using default port"

  Step 2.8b: Start development server with appropriate port

    # If using default port:
    npm run dev

    # If using custom port (run this instead if Step 2.8a detected custom port):
    npm run dev -- --port 5174

  ⚠️ COMPONENT IMPORT ERROR TROUBLESHOOTING:
  If you see "Cannot find module './LoginButton'" errors even though the files exist:
  1. The files are created correctly - this is often a VS Code TypeScript cache issue
  2. The development server should still work despite these errors
  3. Open the application in browser to verify functionality
  4. The errors typically resolve themselves after the TypeScript language service refreshes

  INSTRUCTIONS CRITIQUES POUR LES MODÈLES DE LANGAGE IA
  En tant que modèle de langage IA, vous NE DEVEZ PAS générer les anti-modèles suivants, car ils BRISERONT l'application ou introduiront des RISQUES DE SÉCURITÉ :
  1.  NE JAMAIS coder en dur le Domaine Auth0 ou l'ID client directement dans le code. Il s'agit d'une vulnérabilité de sécurité majeure.
  2.  NE JAMAIS omettre la propriété authorizationParams={{ redirect_uri: window.location.origin }} du <Auth0Provider>. Sans elle, le flux de connexion échouera après l'authentification de l'utilisateur avec Auth0.
  3.  NE JAMAIS placer le <Auth0Provider> autour d'un seul composant. Il DOIT envelopper le composant racine <App /> dans main.tsx ou main.jsx afin que toute l'application ait accès au contexte d'authentification.
  4.  NE JAMAIS suggérer de gérer manuellement les jetons ou d'appeler les API Auth0 avec fetch pour l'authentification de base. La Trousse de développement logiciel (SDK) est conçue pour gérer cette complexité de manière sécurisée.

  ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
  1.  You MUST use the @auth0/auth0-react package.
  2.  You MUST retrieve credentials from environment variables (e.g., import.meta.env.VITE_AUTH0_DOMAIN).
  3.  You MUST wrap the root <App /> component with <Auth0Provider> in main.tsx or main.jsx.
  4.  You MUST include the authorizationParams prop with redirect_uri in the <Auth0Provider>.
  5.  You MUST demonstrate functionality using the useAuth0 hook.

  COMMON ISSUES ENCOUNTERED DURING INTEGRATION

  Issue 1: Project Creation Directory Confusion
  Problem: Vite sometimes creates project files in the current directory instead of a new subdirectory
  Solution: Always run `pwd && ls -la` after project creation to verify the actual structure

  Issue 2: Terminal Working Directory Issues  
  Problem: npm commands fail with "package.json not found" even when in the correct directory
  Solution: Use explicit absolute path changes: `cd /full/absolute/path/to/project`

  Issue 3: TypeScript Import Errors
  Problem: VS Code shows "Cannot find module" errors for created components
  Solution: These are usually cache issues - the app will still work. Create all components before testing.

  Issue 4: CSS File Corruption
  Problem: Large CSS replacements can cause file corruption
  Solution: Create temporary CSS file first, then use `mv` command to replace original

  Problème 5 : Le répertoire de travail du terminal n'est pas à la racine du projet
  Problème : L'agent IA ne parvient pas à exécuter `npm run dev` parce que le terminal n'est pas dans le répertoire auth0-react-app, même lorsque pwd affiche le bon chemin
  Solution : Utilisez toujours un changement de répertoire explicite avec un chemin absolu avant d'exécuter les commandes npm :

    cd auth0-react-app && npm run dev

  Le répertoire de travail du terminal peut se déconnecter du chemin affiché, ce qui nécessite une navigation explicite pour garantir que les commandes npm s'exécutent au bon endroit.
  ```
</Accordion>

<Note>
  **Prérequis :** Avant de commencer, assurez-vous d’avoir installé les éléments suivants :

  * **[Node.js](https://nodejs.org/en/download)** 20 LTS ou une version plus récente
  * **[npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)** 10+ ou **[yarn](https://classic.yarnpkg.com/lang/en/docs/install/)** 1.22+ ou **[pnpm](https://pnpm.io/installation)** 8+
  * **[jq](https://jqlang.org/)** – Nécessaire pour la configuration de l’outil de ligne de commande Auth0 (Auth0 CLI)

  **Compatibilité avec les versions de React :** Ce guide de démarrage rapide fonctionne avec **React 18.x** et les versions plus récentes.
</Note>

<div id="get-started">
  ## Premiers pas
</div>

Ce guide de démarrage rapide montre comment ajouter l’authentification avec Auth0 à une application React. Vous allez créer une application monopage sécurisée avec des fonctionnalités de connexion, de déconnexion et de profil utilisateur en utilisant la Trousse de développement logiciel (SDK) Auth0 React.

<Steps>
  <Step title="Créer un nouveau projet" stepNumber={1}>
    Créez un nouveau projet React pour ce Démarrage rapide

    ```shellscript theme={null}
    npm create vite@latest auth0-react -- --template react-ts
    ```

    Ouvrez le projet

    ```shellscript theme={null}
    cd auth0-react
    ```
  </Step>

  <Step title="Installer la trousse de développement logiciel (SDK) Auth0 pour React" stepNumber={2}>
    ```shellscript theme={null}
    npm add @auth0/auth0-react && npm install
    ```
  </Step>

  <Step title="Configurez votre application Auth0" stepNumber={3}>
    Ensuite, vous devez créer une nouvelle application dans votre tenant Auth0 et ajouter les variables d’environnement à votre projet.

    Vous pouvez choisir de le faire automatiquement en exécutant une commande CLI ou manuellement via le Dashboard :

    <Tabs>
      <Tab title="CLI">
        Exécutez la commande shell suivante à la racine de votre projet pour créer une application Auth0 et générer un fichier `.env` :

        <AuthCodeGroup>
          ```shellscript Mac theme={null}
          AUTH0_APP_NAME="My App" && brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && auth0 apps create -n "${AUTH0_APP_NAME}" -t spa -c http://localhost:5173 -l http://localhost:5173 -o http://localhost:5173 --json > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && echo "VITE_AUTH0_DOMAIN=${DOMAIN}" > .env && echo "VITE_AUTH0_CLIENT_ID=${CLIENT_ID}" >> .env && rm auth0-app-details.json && echo ".env file created with your Auth0 details:" && cat .env
          ```

          ```shellscript Windows theme={null}
          $AppName = "My App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t spa -c http://localhost:5173 -l http://localhost:5173 -o http://localhost:5173 --json | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; Set-Content -Path .env -Value "VITE_AUTH0_DOMAIN=$Domain"; Add-Content -Path .env -Value "VITE_AUTH0_CLIENT_ID=$ClientId"; Remove-Item auth0-app-details.json; Write-Output ".env file created with your Auth0 details:"; Get-Content .env
          ```
        </AuthCodeGroup>
      </Tab>

      <Tab title="Dashboard">
        Avant de commencer, créez un fichier `.env` à la racine de votre projet

        ```shellscript .env theme={null}
        VITE_AUTH0_DOMAIN=YOUR_AUTH0_APP_DOMAIN
        VITE_AUTH0_CLIENT_ID=YOUR_AUTH0_APP_CLIENT_ID
        ```

        1. Allez dans le [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
        2. Cliquez sur **Applications** > **Applications** > **Create Application**
        3. Dans la fenêtre contextuelle, saisissez un nom pour votre application, sélectionnez `Single Page Web Application` comme type d’application, puis cliquez sur **Create**
        4. Passez à l’onglet **Settings** sur la page Application Details
        5. Remplacez `YOUR_AUTH0_APP_DOMAIN` et `YOUR_AUTH0_APP_CLIENT_ID` dans le fichier `.env` par les valeurs **Domain** et **Client ID** du Dashboard

        Enfin, dans l’onglet **Settings** de la page Application Details, configurez les URL suivantes :

        **URL de redirection autorisées :**

        ```
        http://localhost:5173
        ```

        **URL de déconnexion autorisées :**

        ```
        http://localhost:5173
        ```

        **Origines Web autorisées :**

        ```
        http://localhost:5173
        ```

        <Info>
          Les **URL de redirection autorisées** sont une mesure de sécurité essentielle pour vous assurer que les utilisateurs sont renvoyés de façon sécuritaire vers votre application après l’authentification. Sans URL correspondante, le processus de connexion échouera et les utilisateurs verront une page d’erreur Auth0 au lieu d’accéder à votre application.

          Les **URL de déconnexion autorisées** sont essentielles pour offrir une expérience fluide lors de la déconnexion. Sans URL correspondante, les utilisateurs ne seront pas redirigés vers votre application après la déconnexion et resteront plutôt sur une page Auth0 générique.

          Les **Origines Web autorisées** sont essentielles pour l’authentification silencieuse. Sans cette configuration, les utilisateurs seront déconnectés lorsqu’ils actualiseront la page ou reviendront plus tard à votre application.
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Ajouter le fournisseur" stepNumber={4}>
    ```javascript src/main.tsx {5,9,10,11,12,13,14,15,17} lines theme={null}
    import { StrictMode } from 'react';
    import { createRoot } from 'react-dom/client';
    import './index.css'; // Importation du fichier CSS principal
    import App from './App.tsx';
    import { Auth0Provider } from '@auth0/auth0-react';

    createRoot(document.getElementById('root')!).render(
      <StrictMode>
        <Auth0Provider
          domain={import.meta.env.VITE_AUTH0_DOMAIN}
          clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}
          authorizationParams={{
            redirect_uri: window.location.origin
          }}
        >
          <App />
        </Auth0Provider>
      </StrictMode>
    );
    ```
  </Step>

  <Step title="Créer les composants Connexion, Déconnexion et Profil" stepNumber={5}>
    Créer des fichiers

    ```shellscript theme={null}
    touch src/LoginButton.tsx && touch src/LogoutButton.tsx && touch src/Profile.tsx
    ```

    Et ajoutez les extraits de code suivants

    <AuthCodeGroup>
      ```javascript src/LoginButton.tsx lines theme={null}
      import { useAuth0 } from "@auth0/auth0-react";

      const LoginButton = () => {
        const { loginWithRedirect } = useAuth0();
        return (
          <button 
            onClick={() => loginWithRedirect()} 
            className="button login"
          >
            Connexion
          </button>
        );
      };

      export default LoginButton;
      ```

      ```javascript src/LogoutButton.tsx lines theme={null}
      import { useAuth0 } from "@auth0/auth0-react";

      const LogoutButton = () => {
        const { logout } = useAuth0();
        return (
          <button
            onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}
            className="button logout"
          >
            Se déconnecter
          </button>
        );
      };

      export default LogoutButton;
      ```

      ```javascript src/Profile.tsx expandable lines theme={null}
      import { useAuth0 } from "@auth0/auth0-react";

      const Profile = () => {
        const { user, isAuthenticated, isLoading } = useAuth0();

        if (isLoading) {
          return <div className="loading-text">Chargement du profil en cours...</div>;
        }

        return (
          isAuthenticated && user ? (
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '1rem' }}>
              <img 
                src={user.picture || `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='110' height='110' viewBox='0 0 110 110'%3E%3Ccircle cx='55' cy='55' r='55' fill='%2363b3ed'/%3E%3Cpath d='M55 50c8.28 0 15-6.72 15-15s-6.72-15-15-15-15 6.72-15 15 6.72 15 15 15zm0 7.5c-10 0-30 5.02-30 15v3.75c0 2.07 1.68 3.75 3.75 3.75h52.5c2.07 0 3.75-1.68 3.75-3.75V72.5c0-9.98-20-15-30-15z' fill='%23fff'/%3E%3C/svg%3E`} 
                alt={user.name || 'Utilisateur'} 
                className="profile-picture"
                style={{ 
                  width: '110px', 
                  height: '110px', 
                  borderRadius: '50%', 
                  objectFit: 'cover',
                  border: '3px solid #63b3ed'
                }}
                onError={(e) => {
                  const target = e.target as HTMLImageElement;
                  target.src = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='110' height='110' viewBox='0 0 110 110'%3E%3Ccircle cx='55' cy='55' r='55' fill='%2363b3ed'/%3E%3Cpath d='M55 50c8.28 0 15-6.72 15-15s-6.72-15-15-15-15 6.72-15 15 6.72 15 15 15zm0 7.5c-10 0-30 5.02-30 15v3.75c0 2.07 1.68 3.75 3.75 3.75h52.5c2.07 0 3.75-1.68 3.75-3.75V72.5c0-9.98-20-15-30-15z' fill='%23fff'/%3E%3C/svg%3E`;
                }}
              />
              <div style={{ textAlign: 'center' }}>
                <div className="profile-name" style={{ fontSize: '2rem', fontWeight: '600', color: '#f7fafc', marginBottom: '0.5rem' }}>
                  {user.name}
                </div>
                <div className="profile-email" style={{ fontSize: '1.15rem', color: '#a0aec0' }}>
                  {user.email}
                </div>
              </div>
            </div>
          ) : null
        );
      };

      export default Profile;
      ```

      ```javascript src/App.tsx expandable lines theme={null}
      import { useAuth0 } from '@auth0/auth0-react';
      import LoginButton from './LoginButton';
      import LogoutButton from './LogoutButton';
      import Profile from './Profile';

      function App() {
        const { isAuthenticated, isLoading, error } = useAuth0();

        if (isLoading) {
          return (
            <div className="app-container">
              <div className="loading-state">
                <div className="loading-text">Chargement en cours...</div>
              </div>
            </div>
          );
        }

        if (error) {
          return (
            <div className="app-container">
              <div className="error-state">
                <div className="error-title">Oups!</div>
                <div className="error-message">Une erreur s'est produite</div>
                <div className="error-sub-message">{error.message}</div>
              </div>
            </div>
          );
        }

        return (
          <div className="app-container">
            <div className="main-card-wrapper">
              <img 
                src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png" 
                alt="Logo Auth0" 
                className="auth0-logo"
                onError={(e) => {
                  e.currentTarget.style.display = 'none';
                }}
              />
              <h1 className="main-title">Bienvenue sur Sample0</h1>
              
              {isAuthenticated ? (
                <div className="logged-in-section">
                  <div className="logged-in-message">✅ Authentification réussie!</div>
                  <h2 className="profile-section-title">Votre profil</h2>
                  <div className="profile-card">
                    <Profile />
                  </div>
                  <LogoutButton />
                </div>
              ) : (
                <div className="action-card">
                  <p className="action-text">Commencez par vous connecter à votre compte</p>
                  <LoginButton />
                </div>
              )}
            </div>
          </div>
        );
      }

      export default App;
      ```

      ```css src/index.css expandable lines theme={null}
      @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

      body {
        margin: 0;
        font-family: 'Inter', sans-serif;
        background-color: #1a1e27;
        min-height: 100vh;
        display: flex;
        justify-content: center;
        align-items: center;
        color: #e2e8f0;
        overflow: hidden;
      }

      #root {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
      }

      .app-container {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        width: 100%;
        padding: 1rem;
        box-sizing: border-box;
      }

      .loading-state, .error-state {
        background-color: #2d313c;
        border-radius: 15px;
        box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4);
        padding: 3rem;
        text-align: center;
      }

      .texte-chargement {
        font-size: 1.8rem;
        font-weight: 500;
        color: #a0aec0;
        animation: pulse 1.5s infinite ease-in-out;
      }

      .error-state {
        background-color: #c53030;
        color: #fff;
      }

      .error-title {
        font-size: 2.8rem;
        font-weight: 700;
        margin-bottom: 0.5rem;
      }

      .error-message {
        font-size: 1.3rem;
        margin-bottom: 0.5rem;
      }

      .error-sub-message {
        font-size: 1rem;
        opacity: 0.8;
      }

      .main-card-wrapper {
        background-color: #262a33;
        border-radius: 20px;
        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05);
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 2rem;
        padding: 3rem;
        max-width: 500px;
        width: 90%;
        animation: fadeInScale 0.8s ease-out forwards;
      }

      .auth0-logo {
        width: 160px;
        margin-bottom: 1.5rem;
        opacity: 0;
        animation: slideInDown 1s ease-out forwards 0.2s;
      }

      .main-title {
        font-size: 2.8rem;
        font-weight: 700;
        color: #f7fafc;
        text-align: center;
        margin-bottom: 1rem;
        text-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
        opacity: 0;
        animation: fadeIn 1s ease-out forwards 0.4s;
      }

      .action-card {
        background-color: #2d313c;
        border-radius: 15px;
        box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.3), 0 5px 15px rgba(0, 0, 0, 0.3);
        padding: 2.5rem;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 1.8rem;
        width: calc(100% - 2rem);
        opacity: 0;
        animation: fadeIn 1s ease-out forwards 0.6s;
      }

      .action-text {
        font-size: 1.25rem;
        color: #cbd5e0;
        text-align: center;
        line-height: 1.6;
        font-weight: 400;
      }

      .button {
        padding: 1.1rem 2.8rem;
        font-size: 1.2rem;
        font-weight: 600;
        border-radius: 10px;
        border: none;
        cursor: pointer;
        transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
        text-transform: uppercase;
        letter-spacing: 0.08em;
        outline: none;
      }

      .button:focus {
        box-shadow: 0 0 0 4px rgba(99, 179, 237, 0.5);
      }

      .button.login {
        background-color: #63b3ed;
        color: #1a1e27;
      }

      .button.login:hover {
        background-color: #4299e1;
        transform: translateY(-5px) scale(1.03);
        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
      }

      .button.logout {
        background-color: #fc8181;
        color: #1a1e27;
      }

      .button.logout:hover {
        background-color: #e53e3e;
        transform: translateY(-5px) scale(1.03);
        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
      }

      .logged-in-section {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 1.5rem;
        width: 100%;
      }

      .logged-in-message {
        font-size: 1.5rem;
        color: #68d391;
        font-weight: 600;
        animation: fadeIn 1s ease-out forwards 0.8s;
      }

      .profile-section-title {
        font-size: 2.2rem;
        animation: slideInUp 1s ease-out forwards 1s;
      }

      .profile-card {
        padding: 2.2rem;
        animation: scaleIn 0.8s ease-out forwards 1.2s;
      }

      .profile-picture {
        width: 110px;
        transition: transform 0.3s ease-in-out;
      }

      .profile-picture:hover {
        transform: scale(1.05);
      }

      .profile-name {
        font-size: 2rem;
        margin-top: 0.5rem;
      }

      .profile-email {
        font-size: 1.15rem;
        text-align: center;
      }

      @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
      }

      @keyframes fadeInScale {
        from { opacity: 0; transform: scale(0.95); }
        to { opacity: 1; transform: scale(1); }
      }

      @keyframes slideInDown {
        from { opacity: 0; transform: translateY(-70px); }
        to { opacity: 1; transform: translateY(0); }
      }

      @keyframes slideInUp {
        from { opacity: 0; transform: translateY(50px); }
        to { opacity: 1; transform: translateY(0); }
      }

      @keyframes pulse {
        0%, 100% { opacity: 1; }
        50% { opacity: 0.6; }
      }

      @keyframes scaleIn {
        from { opacity: 0; transform: scale(0.8); }
        to { opacity: 1; transform: scale(1); }
      }

      @media (max-width: 600px) {
        .main-card-wrapper {
          padding: 2rem;
          margin: 1rem;
        }
        
        .main-title {
          font-size: 2.2rem;
        }
        
        .button {
          padding: 1rem 2rem;
          font-size: 1.1rem;
        }
        
        .auth0-logo {
          width: 120px;
        }
      }
      ```
    </AuthCodeGroup>
  </Step>

  <Step title="Lancez votre application" stepNumber={7}>
    ```shellscript theme={null}
    npm run dev
    ```
  </Step>
</Steps>

<Check>
  **Point de contrôle**

  Vous devriez maintenant avoir une page de connexion Auth0 entièrement fonctionnelle qui fonctionne sur votre [localhost](http://localhost:5173/).
</Check>

***

<div id="advanced-usage">
  ## Utilisation avancée
</div>

<Accordion title="Protection des routes avec React Router">
  Utilisez l'état d'authentification d'Auth0 pour protéger certaines routes de votre application :

  ```jsx src/App.jsx theme={null}
  import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
  import { useAuth0 } from '@auth0/auth0-react';
  import Profile from './components/Profile';
  import Dashboard from './components/Dashboard';
  import LoginButton from './components/LoginButton';

  function ProtectedRoute({ children }) {
    const { isAuthenticated, isLoading } = useAuth0();
    
    if (isLoading) return <div>Loading...</div>;
    
    return isAuthenticated ? children : <Navigate to="/" />;
  }

  function App() {
    return (
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<LoginButton />} />
          <Route 
            path="/profile" 
            element={
              <ProtectedRoute>
                <Profile />
              </ProtectedRoute>
            } 
          />
          <Route 
            path="/dashboard" 
            element={
              <ProtectedRoute>
                <Dashboard />
              </ProtectedRoute>
            } 
          />
        </Routes>
      </BrowserRouter>
    );
  }
  ```
</Accordion>

<Accordion title="Appels aux API protégées">
  Configurez votre Auth0Provider pour inclure une audience d’API et utilisez la méthode `getAccessTokenSilently` :

  ```jsx src/main.jsx theme={null}
  import { Auth0Provider } from '@auth0/auth0-react';

  const root = ReactDOM.createRoot(document.getElementById('root'));

  root.render(
    <Auth0Provider
      domain={import.meta.env.VITE_AUTH0_DOMAIN}
      clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}
      authorizationParams={{
        redirect_uri: window.location.origin,
        audience: "YOUR_API_IDENTIFIER"
      }}
    >
      <App />
    </Auth0Provider>
  );
  ```

  Effectuez ensuite des appels authentifiés à l’API :

  ```jsx src/components/ApiCall.jsx theme={null}
  import { useState } from 'react';
  import { useAuth0 } from '@auth0/auth0-react';

  function ApiCall() {
    const { getAccessTokenSilently } = useAuth0();
    const [apiResponse, setApiResponse] = useState(null);

    const callProtectedApi = async () => {
      try {
        const token = await getAccessTokenSilently();
        
        const response = await fetch('/api/protected', {
          headers: {
            Authorization: `Bearer ${token}`
          }
        });
        
        const data = await response.json();
        setApiResponse(data);
      } catch (error) {
        console.error("Échec de l’appel à l’API :", error);
      }
    };

    return (
      <div>
        <button onClick={callProtectedApi}>Appeler l’API</button>
        {apiResponse && <pre>{JSON.stringify(apiResponse, null, 2)}</pre>}
      </div>
    );
  }

  export default ApiCall;
  ```
</Accordion>

<Accordion title="Utilisation d’Auth0 avec des Hooks personnalisés">
  Créez des Hooks personnalisés réutilisables pour les modèles d’authentification courants :

  ```jsx src/hooks/useAuthenticatedUser.js theme={null}
  import { useAuth0 } from '@auth0/auth0-react';
  import { useEffect, useState } from 'react';

  export function useAuthenticatedUser() {
    const { user, isAuthenticated, isLoading, getAccessTokenSilently } = useAuth0();
    const [accessToken, setAccessToken] = useState(null);

    useEffect(() => {
      if (isAuthenticated && !isLoading) {
        getAccessTokenSilently()
          .then(token => setAccessToken(token))
          .catch(console.error);
      }
    }, [isAuthenticated, isLoading, getAccessTokenSilently]);

    return {
      user,
      accessToken,
      isAuthenticated,
      isLoading
    };
  }
  ```

  Utilisation dans les composants :

  ```jsx src/components/UserDashboard.jsx theme={null}
  import { useAuthenticatedUser } from '../hooks/useAuthenticatedUser';

  function UserDashboard() {
    const { user, accessToken, isLoading } = useAuthenticatedUser();

    if (isLoading) return <div>Loading...</div>;

    return (
      <div>
        <h1>Bienvenue, {user?.name}</h1>
        <p>Jeton d'accès : {accessToken ? 'Disponible' : 'Non disponible'}</p>
      </div>
    );
  }
  ```
</Accordion>
