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

# Ajouter la connexion à votre application React Router

> Ce guide explique comment intégrer Auth0 à une application React Router (mode cadre d'applications, version 7 ou ultérieure) à l'aide de la trousse SDK Auth0 React Router.

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

export const CreateInteractiveApp = ({placeholderText = "Auth0", appType = "regular_web", allowedCallbackUrls = ["localhost:3000"], allowedLogoutUrls = ["localhost:3000"], allowedOriginUrls = ["localhost:3000"]}) => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [storeReady, setStoreReady] = useState(false);
  const [displayForm, setDisplayForm] = useState(true);
  useEffect(() => {
    const init = () => setStoreReady(true);
    if (window.rootStore) {
      window.rootStore.clientStore.setSelectedClient(null);
      window.rootStore.clientStore.setSelectedClientSecret(undefined);
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
    };
  }, []);
  useEffect(() => {
    if (!storeReady) return;
    const disposer = autorun(() => {
      const rootStore = window.rootStore;
      setIsAuthenticated(rootStore.sessionStore.isAuthenticated);
    });
    return () => {
      disposer();
    };
  }, [storeReady]);
  if (!storeReady || typeof window === "undefined" || !displayForm) {
    return <></>;
  }
  const login = () => {
    const baseUrl = window.rootStore.config.apiBaseUrl;
    const returnTo = encodeURIComponent(window.location.href);
    window.location.href = `${baseUrl}/auth/user/login?returnTo=${returnTo}`;
  };
  const Card = ({className = "", children}) => {
    return <div className={`
          flex border rounded-2xl
          border-gray-950/10 dark:border-white/10
          py-3.5 px-4 gap-2
          text-sm text-gray-900 dark:text-gray-200
          ${className}
        `}>
        {children}
      </div>;
  };
  const Button = ({children, ...props}) => {
    return <button className="bg-[--button-primary] text-[--foreground-inverse] px-[1.125rem] py-1.5 rounded-lg font-medium" {...props}>
        {children}
      </button>;
  };
  const CreateApplicationForm = () => {
    const [name, setName] = useState("");
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState("");
    const handleSubmit = async () => {
      if (!name.trim()) {
        setError("Le nom de l'application est obligatoire");
        return;
      }
      setIsLoading(true);
      setError(null);
      try {
        await window.rootStore.clientStore.createClient({
          name: name.trim(),
          app_type: appType,
          callbacks: allowedCallbackUrls,
          allowed_logout_urls: allowedLogoutUrls,
          web_origins: allowedOriginUrls,
          client_metadata: {
            created_by: "quickstart-docs-app-creation-component"
          }
        });
        setDisplayForm(false);
      } catch (err) {
        console.error("Erreur lors de la création du client :", err);
        const errorMessage = err instanceof Error ? err.message : "Échec de la création de l'application";
        setError(errorMessage);
      } finally {
        setIsLoading(false);
      }
    };
    return <Card className="flex-col items-start p-4 gap-3.75">
        <span className="font-medium text-gray-900 dark:text-gray-200">Créer une Auth0 App</span>
        <div className="w-full flex gap-2">
          <input id="app-name" name={name} className="
              w-full max-w-[448px] h-11 py-2 px-4 
              border rounded-lg border-gray-950/10 dark:border-white/10 
              text-gray-900 dark:text-gray-200
              focus:outline-none dark:focus:outline-none
            " placeholder={`Mon application ${placeholderText}`} value={name} onChange={e => setName(e.target.value)} />
          <Button onClick={handleSubmit}>{isLoading ? "Création en cours..." : "Créer"}</Button>
        </div>
        {error && <p className="text-red-500">{error}</p>}
      </Card>;
  };
  const SignInForm = () => {
    return <Card className="items-center">
        <Button onClick={login}>Se connecter</Button> <span>pour créer l'application</span>
      </Card>;
  };
  return isAuthenticated ? <CreateApplicationForm /> : <SignInForm />;
};

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASQUÉ*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

<HowToSchema />

<Warning>
  `@auth0/auth0-react-router` est actuellement en version **bêta** (`1.0.0-beta.2`). L’API pourrait changer d’ici la version stable 1.0.
</Warning>

<Accordion title="Utiliser l’IA pour intégrer Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  Si vous utilisez un assistant de codage IA comme Claude Code, Cursor ou GitHub Copilot, vous pouvez ajouter automatiquement l’authentification Auth0 en quelques minutes grâce aux [compétences d’agent](https://agentskills.io/home).

  **Installation :**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0
  ```

  **Ensuite, demandez à votre assistant IA :**

  ```text theme={null}
  Add Auth0 authentication to my React Router app
  ```

  Votre assistant IA se chargera automatiquement de créer votre application Auth0, de récupérer les informations d’identification, d’installer `@auth0/auth0-react-router`, de configurer le fournisseur et de configurer vos routes. [Documentation complète sur les compétences d’agent →](/docs/fr-ca/quickstart/agent-skills)
</Accordion>

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  **Informations requises :** Avant de commencer, assurez-vous d’avoir installé les éléments suivants :

  * **[Node.js](https://nodejs.org/en/download)** 18 ou version ultérieure (20 LTS recommandée)
  * **[npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)** 9+, **[yarn](https://classic.yarnpkg.com/lang/en/docs/install/)** 1.22+ ou **[pnpm](https://pnpm.io/installation)** 8+
  * **[jq](https://jqlang.org/)** – requis pour la configuration avec l’interface de ligne de commande (CLI) d’Auth0
  * React Router en mode cadre d’applications, v7 ou version ultérieure (fichier `react-router.config.ts` présent)
</Callout>

<h2 id="get-started">
  Premiers pas
</h2>

Ce guide de démarrage rapide vous montre comment ajouter l’authentification Auth0 à une application React Router. Vous allez créer une application sécurisée dotée de fonctionnalités de connexion, de déconnexion et de profil utilisateur à l’aide de la trousse SDK Auth0 React Router. La trousse SDK gère le flux OIDC côté serveur et stocke la session dans un témoin chiffré en JWE; les jetons ne se rendent donc jamais jusqu’au navigateur.

export function generateRandomString(length) {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  return Array.from({
    length
  }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
}

export const envSnippet = `AUTH0_DOMAIN={yourDomain}
AUTH0_CLIENT_ID={yourClientId}
AUTH0_CLIENT_SECRET={yourClientSecret}
AUTH0_SESSION_SECRET=${generateRandomString(32)}
AUTH0_APP_BASE_URL=http://localhost:5173`;

<Steps>
  <Step title="Créer un nouveau projet React Router" stepNumber={1}>
    Créez un nouveau projet React Router pour ce guide de démarrage rapide :

    ```shellscript theme={null}
    npx create-react-router@latest my-app
    ```

    Ouvrez le projet :

    ```shellscript theme={null}
    cd my-app && npm install
    ```

    <Note>
      Ignorez cette étape si vous ajoutez Auth0 à une application React Router existante.
    </Note>
  </Step>

  <Step title="Installez le SDK Auth0 React Router" stepNumber={2}>
    ```shellscript theme={null}
    npm install @auth0/auth0-react-router
    ```
  </Step>

  <Step title="Configurer Auth0" stepNumber={3}>
    Créez une application Auth0 et définissez les URL de rappel et de déconnexion.

    <Tabs>
      <Tab title="Configuration rapide">
        <CreateInteractiveApp type="regular_web" callbackUrl="http://localhost:5173/auth/callback" logoutUrl="http://localhost:5173" />
      </Tab>

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

        <CodeGroup>
          ```shellscript Mac theme={null}
          # Installer Auth0 CLI (si ce n’est pas déjà fait)
          brew tap auth0/auth0-cli && brew install auth0

          # Configurer l’application Auth0 et générer le fichier .env
          auth0 qs setup --app --type regular --framework react-router --port 5173 --name "My React Router App"
          ```

          ```powershell Windows theme={null}
          # Installer Auth0 CLI (si ce n’est pas déjà fait)
          scoop bucket add auth0 https://github.com/auth0/scoop-auth0-cli.git
          scoop install auth0

          # Configurer l’application Auth0 et générer le fichier .env
          auth0 qs setup --app --type regular --framework react-router --port 5173 --name "My React Router App"
          ```
        </CodeGroup>

        <Note>
          Cette commande crée une application Web standard Auth0 configurée pour `http://localhost:5173` et génère un fichier `.env` contenant toutes les informations d’identification requises. Si vous choisissez cette option, passez l’étape 4.
        </Note>
      </Tab>

      <Tab title="Dashboard">
        1. Accédez à [Auth0 Dashboard](https://manage.auth0.com/) → **Applications > Applications**
        2. Cliquez sur **Create Application**, saisissez un nom et sélectionnez **Regular Web Application**
        3. Cliquez sur **Create**
        4. Ouvrez l’onglet **Settings** (paramètres de l’application)
        5. Remplissez les champs suivants :

        | Champ | Valeur |
        | - | - |
        | Allowed Callback URLs | `http://localhost:5173/auth/callback` |
        | Allowed Logout URLs | `http://localhost:5173` |

        6. Cliquez sur **Save Changes**
        7. Copiez les valeurs **Domain** et **Client ID** dans les paramètres de l’application — vous en aurez besoin à l’étape suivante
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configurer les variables d’environnement" stepNumber={4}>
    Créez un fichier `.env` à la racine de votre projet :

    <AuthCodeBlock children={envSnippet} language="shellscript" filename=".env" />

    | Variable | Où la trouver |
    | - | - |
    | `AUTH0_DOMAIN` | Paramètres de l’application → Domaine |
    | `AUTH0_CLIENT_ID` | Paramètres de l’application → ID client |
    | `AUTH0_CLIENT_SECRET` | Paramètres de l’application → Secret client |
    | `AUTH0_SESSION_SECRET` | Une chaîne aléatoire d’au moins 32 caractères — générée automatiquement dans l’extrait ci-dessus |
    | `AUTH0_APP_BASE_URL` | L’URL de base de votre application — `http://localhost:5173` pour le développement local |

    <Warning>
      Ne validez jamais le fichier `.env` dans votre système de gestion de versions. Ajoutez-le à `.gitignore` avant votre première validation.
    </Warning>
  </Step>

  <Step title="Créer l’instance du serveur Auth0" stepNumber={5}>
    Créez `app/auth0.server.ts`. Le suffixe `.server.ts` indique au bundler de React Router d'exclure ce fichier du paquet client, afin que vos secrets restent uniquement côté serveur.

    ```ts app/auth0.server.ts theme={null}
    import { Auth0Server, registerAuth0Instance } from '@auth0/auth0-react-router/server';

    export const auth0 = new Auth0Server();
    registerAuth0Instance(auth0);
    ```
  </Step>

  <Step title="Ajouter les routes d’authentification" stepNumber={6}>
    Créez une route générique (splat) qui prend en charge tous les chemins `/auth/*`. `handleAuth` achemine en interne les requêtes vers `handleLogin`, `handleCallback`, `handleLogout` et `handleBackchannelLogout` selon le chemin de l'URL et la méthode HTTP.

    ```tsx app/routes/auth.$.tsx theme={null}
    import { handleAuth } from '@auth0/auth0-react-router/server';
    import { auth0 } from '../auth0.server';

    export const loader = ({ request }: { request: Request }) =>
      handleAuth(auth0, request);

    export const action = ({ request }: { request: Request }) =>
      handleAuth(auth0, request);
    ```

    Enregistrez la route dans votre configuration de routes :

    ```ts app/routes.ts theme={null}
    import { type RouteConfig, route } from '@react-router/dev/routes';

    export default [
      route('auth/*', 'routes/auth.$.tsx'),
      // ... vos autres routes
    ] satisfies RouteConfig;
    ```
  </Step>

  <Step title="Configurer la mise en page racine" stepNumber={7}>
    Ajoutez `Auth0Provider` et `rootAuthLoader` à `app/root.tsx`. `rootAuthLoader` déchiffre le témoin de session et transmet l'état d'authentification au fournisseur — aucun jeton n'est envoyé au navigateur.

    ```tsx app/root.tsx expandable theme={null}
    import { Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router';
    import { Auth0Provider } from '@auth0/auth0-react-router';
    import { rootAuthLoader } from '@auth0/auth0-react-router/server';
    import type { Route } from './+types/root';

    export const loader = ({ request }: Route.LoaderArgs) =>
      rootAuthLoader(request);

    export default function Root() {
      return (
        <html lang="en">
          <head>
            <meta charSet="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1" />
            <Meta />
            <Links />
          </head>
          <body>
            <Auth0Provider>
              <Outlet />
            </Auth0Provider>
            <ScrollRestoration />
            <Scripts />
          </body>
        </html>
      );
    }
    ```

    <Note>
      `Auth0Provider` lit les données de session à partir de `useRouteLoaderData('root')`; la route racine doit donc avoir l'identifiant `root`. Avec le routage basé sur les fichiers, React Router définit automatiquement cet identifiant à partir du nom du fichier. Avec une configuration de routes personnalisée, transmettez `{ id: 'root' }` à l'appel `layout()`.
    </Note>
  </Step>

  <Step title="Ajouter la connexion et la déconnexion" stepNumber={8}>
    Utilisez les composants intégrés pour afficher les boutons de connexion et de déconnexion. `LoginButton` redirige vers `/auth/login` et `LogoutButton` redirige vers `/auth/logout`. Auth0 gère le flux OIDC, puis redirige l’utilisateur vers votre application une fois la connexion effectuée.

    ```tsx app/routes/_index.tsx theme={null}
    import {
      AuthLoading,
      LoginButton,
      LogoutButton,
      SignedIn,
      SignedOut,
    } from '@auth0/auth0-react-router';

    export default function Home() {
      return (
        <main>
          <h1>Welcome</h1>
          <AuthLoading>
            <p>Loading…</p>
          </AuthLoading>
          <SignedOut>
            <LoginButton>Log in</LoginButton>
          </SignedOut>
          <SignedIn>
            <LogoutButton>Log out</LogoutButton>
          </SignedIn>
        </main>
      );
    }
    ```
  </Step>

  <Step title="Afficher le profil utilisateur" stepNumber={9}>
    Utilisez le hook `useUser` pour accéder au profil de l'utilisateur authentifié dans n'importe quel composant client. Combinez-le avec `requireSession` dans le loader pour bloquer les requêtes non authentifiées directement sur le serveur, avant même le rendu de la page.

    ```tsx app/routes/profile.tsx theme={null}
    import { useUser } from '@auth0/auth0-react-router';
    import { requireSession } from '@auth0/auth0-react-router/server';
    import type { Route } from './+types/profile';

    export const loader = async ({ request }: Route.LoaderArgs) => {
      await requireSession(request);
      return null;
    };

    export default function Profile() {
      const user = useUser();

      return (
        <main>
          <h1>Profile</h1>
          {user && (
            <div>
              <img src={user.picture} alt={user.name ?? ''} width={80} height={80} />
              <p><strong>{user.name}</strong></p>
              <p>{user.email}</p>
            </div>
          )}
        </main>
      );
    }
    ```
  </Step>

  <Step title="Exécutez votre application" stepNumber={10}>
    ```shellscript theme={null}
    npm run dev
    ```

    Ouvrez `http://localhost:5173` dans votre navigateur et cliquez sur **Log in**. Vous serez redirigé vers la page de connexion universelle d’Auth0. Une fois connecté, vous serez redirigé vers votre application.
  </Step>
</Steps>

<Check>
  La connexion et la déconnexion fonctionnent maintenant dans votre application. La session est stockée dans un témoin chiffré en JWE — les jetons d'accès restent sur le serveur et ne sont jamais transmis au navigateur.
</Check>

<h2 id="troubleshooting">
  Dépannage
</h2>

<AccordionGroup>
  <Accordion title="JWEDecryptionFailed — impossible de déchiffrer le témoin de session">
    **Cause :** `AUTH0_SESSION_SECRET` a été modifié après l’émission d’un témoin de session, ou la valeur compte moins de 32 caractères.

    **Solution :** Effacez les témoins de votre navigateur pour `localhost`, assurez-vous que `AUTH0_SESSION_SECRET` compte au moins 32 caractères, puis redémarrez le serveur de développement. Pour générer un nouveau secret : `openssl rand -hex 32`.
  </Accordion>

  <Accordion title="URL de rappel non concordante — Auth0 renvoie une erreur après la connexion">
    **Cause :** L’URL de redirection reçue par Auth0 ne correspond à aucune des valeurs définies dans les URL de rappel autorisées (Allowed Callback URLs).

    **Solution :** Dans [Auth0 Dashboard](https://manage.auth0.com/) → **Applications > Applications** → sélectionnez votre application → **Application Settings**, assurez-vous que **Allowed Callback URLs** est défini à `http://localhost:5173/auth/callback`. Supprimez toute barre oblique finale ou tout espace superflu, puis cliquez sur **Save Changes**.
  </Accordion>

  <Accordion title="Erreur 404 sur /auth/login — route introuvable">
    **Cause :** La route générique `auth.$.tsx` est absente ou n’est pas enregistrée dans `routes.ts`.

    **Solution :** Assurez-vous que `app/routes/auth.$.tsx` existe et que `app/routes.ts` inclut `route('auth/*', 'routes/auth.$.tsx')`. Redémarrez le serveur de développement après avoir modifié `routes.ts`.
  </Accordion>

  <Accordion title="useUser renvoie null après la connexion">
    **Cause :** `rootAuthLoader` n’est pas exporté depuis `app/root.tsx`, ou la route racine n’a pas l’identifiant `root`.

    **Solution :** Assurez-vous que `app/root.tsx` exporte `export const loader = ({ request }) => rootAuthLoader(request)`. Si vous utilisez une configuration de routes personnalisée, enregistrez la mise en page racine comme suit : `layout('root.tsx', { id: 'root' }, [...routes])`.
  </Accordion>

  <Accordion title="TypeError sur context.get — le logiciel médiateur ne fonctionne pas">
    **Cause :** `defineRouteAuth` et `auth0Middleware` nécessitent React Router 7.9.0 ou une version ultérieure, puisque c’est cette version qui a introduit l’API de logiciel médiateur.

    **Solution :** Mettez à niveau `react-router` vers `>=7.9.0`, ou protégez plutôt chaque route individuellement à l’aide de `requireSession` / `requireUser` dans chaque chargeur.
  </Accordion>
</AccordionGroup>

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

<AccordionGroup>
  <Accordion title="Appeler une API côté serveur avec un jeton d'accès">
    Ajoutez `AUTH0_AUDIENCE` au fichier `.env` avec l'identifiant de votre API (disponible dans [Auth0 Dashboard](https://manage.auth0.com/) → **Applications > APIs** → **API Settings → Identifier**). Utilisez ensuite `getAccessToken` dans un chargeur (loader) — le jeton n'est jamais transmis au navigateur :

    ```ts app/routes/data.tsx theme={null}
    import { getAccessToken } from '@auth0/auth0-react-router/server';
    import { TokenError } from '@auth0/auth0-react-router/errors';

    export const loader = async ({ request }) => {
      let token: string;
      try {
        token = await getAccessToken(request);
      } catch (err) {
        if (err instanceof TokenError) {
          return new Response(null, { status: 302, headers: { Location: '/auth/login' } });
        }
        throw err;
      }
      const data = await fetch('https://api.example.com/items', {
        headers: { Authorization: `Bearer ${token}` },
      }).then(r => r.json());
      return { data };
    };
    ```
  </Accordion>

  <Accordion title="Protection des routes en fonction des rôles">
    Utilisez le logiciel médiateur `defineRouteAuth` (React Router ≥ 7.9.0) pour imposer des rôles au niveau des routes. Par défaut, les rôles sont lus à partir de la demande personnalisée `https://auth0.com/claims/roles` :

    ```ts app/routes/admin.tsx theme={null}
    import { defineRouteHandle } from '@auth0/auth0-react-router';
    import { defineRouteAuth, auth0UserContext } from '@auth0/auth0-react-router/server';

    export const handle = defineRouteHandle({ role: 'admin' });

    export const middleware = defineRouteAuth({ role: 'admin' }).middleware;

    export const loader = ({ context }) => {
      const user = context.get(auth0UserContext);
      return { user };
    };
    ```

    Les requêtes qui n'ont pas le rôle requis reçoivent une réponse `403`.
  </Accordion>

  <Accordion title="Mode SPA (PKCE côté client)">
    La trousse SDK peut fonctionner entièrement côté client grâce à `@auth0/auth0-spa-js`. Ajoutez `VITE_AUTH0_DOMAIN` et `VITE_AUTH0_CLIENT_ID` à votre fichier `.env` — `Auth0Provider` détecte automatiquement ces variables et bascule vers le flux PKCE. Aucune autre modification du code n'est requise.

    ```shellscript theme={null}
    # Ajouts au fichier .env pour le mode SPA
    VITE_AUTH0_DOMAIN={yourDomain}
    VITE_AUTH0_CLIENT_ID={yourClientId}
    ```

    <Warning>
      Ne définissez pas les variables `AUTH0_*` et `VITE_AUTH0_*` simultanément. Le mode hybride n'est pas pris en charge — si les deux sont présentes, la déconnexion en mode SPA n'effacera pas le témoin de session côté serveur.
    </Warning>
  </Accordion>
</AccordionGroup>
