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

# Ajouter la connexion à votre application Ionic Vue avec Capacitor

> Ce guide explique comment intégrer Auth0 à une application Ionic Vue avec Capacitor à l’aide du Auth0 Vue SDK.

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>;
};

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()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "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>;
};

<HowToSchema />

<Accordion title="Utilisez l’IA pour intégrer Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  Si vous utilisez un assistant IA de programmation comme Claude Code, Cursor ou GitHub Copilot, vous pouvez ajouter automatiquement l’authentification Auth0 en quelques minutes à l’aide d’[agent skills](https://agentskills.io/home).
  Commencez par installer les Auth0 agent skills :

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

  Ensuite, demandez à votre assistant IA :

  ```text theme={null}
  Add Auth0 authentication to my Ionic Vue app
  ```

  Votre assistant IA créera automatiquement votre application Auth0, récupérera les identifiants, installera le Auth0 Vue SDK et les plugins Capacitor, configurera les liens profonds et mettra en place les flux de connexion et de déconnexion avec l’intégration au navigateur natif. Pour en savoir plus, consultez [Auth0 agent skills](/docs/fr-ca/quickstart/agent-skills).
</Accordion>

<div id="get-started">
  ## Pour commencer
</div>

Ce Quickstart explique comment ajouter l’authentification Auth0 à une application Ionic Vue exécutée sur iOS et Android avec Capacitor. Vous créerez une application mobile sécurisée avec des fonctionnalités de login, de logout et de profil utilisateur à l’aide de l’Auth0 Vue SDK et des plugins de navigateur natifs de Capacitor.

<Steps>
  <Step title="Créer un nouveau projet" stepNumber={1}>
    Créer un nouveau projet Ionic Vue avec Capacitor

    ```shellscript theme={null}
    npx ionic start auth0-ionic-vue blank --type=vue --capacitor
    ```

    Ouvrez le projet

    ```shellscript theme={null}
    cd auth0-ionic-vue
    ```

    <Warning>
      Assurez-vous d’utiliser le paquet `@ionic/cli` (et non le paquet `ionic`, qui est obsolète). Si vous voyez des erreurs liées à `--npm-client` pendant la création du projet, mettez votre CLI à jour :

      ```shellscript theme={null}
      npm uninstall -g ionic
      npm i -g @ionic/cli
      ```
    </Warning>
  </Step>

  <Step title="Installez le SDK Auth0 Vue et les plugiciels de Capacitor" stepNumber={2}>
    ```shellscript theme={null}
    npm install @auth0/auth0-vue @capacitor/browser @capacitor/app
    ```

    <Info>
      **[`@capacitor/browser`](https://capacitorjs.com/docs/apis/browser)** ouvre la page Auth0 Universal Login dans le navigateur système de l’appareil (SFSafariViewController sur iOS, Chrome Custom Tabs sur Android) pour une authentification sécurisée.

      **[`@capacitor/app`](https://capacitorjs.com/docs/apis/app)** écoute les événements de lien profond afin que votre application puisse gérer le callback OAuth lorsque Auth0 redirige l’utilisateur après la connexion.
    </Info>
  </Step>

  <Step title="Configurez votre Auth0 App" stepNumber={3}>
    Ensuite, vous devez créer une nouvelle application dans votre tenant Auth0. Les applications Ionic Capacitor utilisent le type d’application **Native** avec des URL de callback utilisant un schéma d’URL personnalisé.

    Vous avez trois options pour configurer votre application Auth0 : utiliser l’outil Quick Setup (recommandé), exécuter une commande CLI ou faire la configuration manuellement dans le Dashboard :

    <Tabs>
      <Tab title="Configuration rapide (recommandée)">
        Créez une application Auth0 **Native** et obtenez vos identifiants.

        <CreateInteractiveApp placeholderText="Ionic Vue" appType="native" allowedCallbackUrls={[]} allowedLogoutUrls={[]} allowedOriginUrls={["capacitor://localhost", "http://localhost"]} />

        Après avoir créé votre application, notez les valeurs **Domain** et **Client ID** pour l’étape suivante.

        <Note>
          Vous devrez aussi configurer les URL de callback et de logout dans le Dashboard. Consultez la configuration des URL ci-dessous.
        </Note>
      </Tab>

      <Tab title="CLI">
        Exécutez les commandes suivantes dans le répertoire racine de votre projet pour créer une application Auth0 :

        <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 native --framework ionic-vue --build-tool vite --name "My Ionic Vue 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 native --framework ionic-vue --build-tool vite --name "My Ionic Vue App"
          ```
        </CodeGroup>

        <Note>
          Cette commande va :

          1. Vérifier si vous êtes authentifié (et vous inviter à vous connecter au besoin)
          2. Créer une application Auth0 Native
          3. Générer un fichier `.env` contenant votre domaine Auth0 et votre ID client
        </Note>
      </Tab>

      <Tab title="Dashboard">
        1. Accédez au [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
        2. Cliquez sur **Applications** > **Applications** > **Create Application**
        3. Entrez un nom pour votre application (par exemple, `Ionic Vue App`), sélectionnez **Native** comme type d’application, puis cliquez sur **Create**
        4. Passez à l’onglet **Settings** et notez vos valeurs **Domain** et **Client ID**

        <Info>
          Dans ce guide, `YOUR_PACKAGE_ID` correspond à l’ID du package de votre application. Vous pouvez le trouver et le configurer dans le champ `appId` de votre fichier `capacitor.config.ts`. Consultez le [schéma de configuration de Capacitor](https://capacitorjs.com/docs/config#schema) pour plus d’info.
        </Info>

        Configurez les URL suivantes dans l’onglet **Settings** de la page Details de votre Application :

        **Allowed Callback URLs:**

        ```text theme={null}
        YOUR_PACKAGE_ID://{yourDomain}/capacitor/YOUR_PACKAGE_ID/callback
        ```

        **Allowed Logout URLs:**

        ```text theme={null}
        YOUR_PACKAGE_ID://{yourDomain}/capacitor/YOUR_PACKAGE_ID/callback
        ```

        **Allowed Origins:**

        ```text theme={null}
        capacitor://localhost, http://localhost
        ```

        <Info>
          Les **Allowed Callback URLs** constituent une mesure de sécurité essentielle pour garantir que les utilisateurs sont redirigés de façon sécuritaire vers votre application après l’authentication. Sans URL correspondante, le processus de connexion échouera et les utilisateurs seront bloqués sur une page d’erreur Auth0 au lieu d’accéder à votre application.

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

          Les **Allowed Origins** doivent inclure `capacitor://localhost` (iOS) et `http://localhost` (Android) pour les requêtes d’application native vers Auth0.
        </Info>
      </Tab>
    </Tabs>

    <Tip>
      Si vous avez utilisé **Quick Setup** ou **CLI**, accédez à l’onglet **Settings** de votre application dans le [Auth0 Dashboard](https://manage.auth0.com/#/applications) pour configurer les URL de callback et de logout indiquées dans l’onglet Dashboard ci-dessus.
    </Tip>
  </Step>

  <Step title="Configurer le plugin Auth0" stepNumber={4}>
    ```typescript src/main.ts {5,6,8,9,14,15,16,17,18,19,20,21,22,23} lines theme={null}
    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import { IonicVue } from '@ionic/vue'
    import { createAuth0 } from '@auth0/auth0-vue'
    import config from '../capacitor.config'

    // Créer l’URL de rappel à partir de l’ID du paquet de votre application
    const redirect_uri = `${config.appId}://{yourDomain}/capacitor/${config.appId}/callback`

    const app = createApp(App)
      .use(IonicVue)
      .use(router)

    app.use(
      createAuth0({
        domain: '{yourDomain}',
        clientId: '{yourClientId}',
        useRefreshTokens: true,
        useRefreshTokensFallback: false,
        authorizationParams: {
          redirect_uri,
        },
      })
    )

    router.isReady().then(() => {
      app.mount('#app')
    })
    ```

    <Info>
      * **`useRefreshTokens: true`** — Les navigateurs mobiles bloquent les cookies tiers, donc l’authentification silencieuse basée sur un iframe ne fonctionne pas. Les jetons d’actualisation appellent directement le point de terminaison `/oauth/token`.
      * **`useRefreshTokensFallback: false`** — Empêche le SDK de tenter la solution de secours basée sur un iframe, qui n’est pas offerte sur mobile.
      * **`router.isReady().then(...)`** — Garantit que Vue Router est entièrement initialisé avant que le SDK traite le callback OAuth, ce qui évite les conflits de synchronisation.
    </Info>

    <Warning>
      Pour conserver l’authentification après avoir fermé puis rouvert l’application, vous pouvez définir `cacheLocation` sur `localstorage`, mais sachez qu’il y a [des risques à stocker des jetons dans localstorage](https://auth0.com/docs/libraries/auth0-single-page-app-sdk#change-storage-options). De plus, `localstorage` doit être considéré comme **temporaire** dans les applications Capacitor, car les données pourraient être récupérées de manière inattendue. Consultez aussi les [recommandations sur le stockage dans la documentation de Capacitor](https://capacitorjs.com/docs/guides/storage#why-cant-i-just-use-localstorage-or-indexeddb).
    </Warning>
  </Step>

  <Step title="Créer des composants d’authentification" stepNumber={5}>
    Créer des fichiers de composants

    <CodeGroup>
      ```shellscript Mac/Linux theme={null}
      mkdir -p src/components && touch src/components/LoginButton.vue && touch src/components/LogoutButton.vue && touch src/components/UserProfile.vue
      ```

      ```powershell Windows theme={null}
      New-Item -ItemType Directory -Force -Path src/components
      New-Item -ItemType File -Path src/components/LoginButton.vue
      New-Item -ItemType File -Path src/components/LogoutButton.vue
      New-Item -ItemType File -Path src/components/UserProfile.vue
      ```
    </CodeGroup>

    Ajoutez le code suivant aux nouveaux composants, puis mettez à jour les fichiers `App.vue` et `HomePage.vue` existants

    <AuthCodeGroup>
      ```vue src/components/LoginButton.vue lines theme={null}
      <template>
        <ion-button @click="login" expand="block">Log in</ion-button>
      </template>

      <script setup lang="ts">
      import { useAuth0 } from '@auth0/auth0-vue'
      import { Browser } from '@capacitor/browser'
      import { IonButton } from '@ionic/vue'

      const { loginWithRedirect } = useAuth0()

      const login = async () => {
        await loginWithRedirect({
          openUrl: (url: string) =>
            Browser.open({ url, windowName: '_self' }),
        })
      }
      </script>
      ```

      ```vue src/components/LogoutButton.vue lines theme={null}
      <template>
        <ion-button @click="onLogout" expand="block" color="danger">
          Log out
        </ion-button>
      </template>

      <script setup lang="ts">
      import { useAuth0 } from '@auth0/auth0-vue'
      import { Browser } from '@capacitor/browser'
      import { IonButton } from '@ionic/vue'
      import config from '../../capacitor.config'

      const returnTo = `${config.appId}://{yourDomain}/capacitor/${config.appId}/callback`

      const { logout } = useAuth0()

      const onLogout = async () => {
        await logout({
          logoutParams: { returnTo },
          openUrl: (url: string) =>
            Browser.open({ url, windowName: '_self' }),
        })
      }
      </script>
      ```

      ```vue src/components/UserProfile.vue expandable lines theme={null}
      <template>
        <div v-if="isLoading" class="ion-text-center">
          <p>Loading profile...</p>
        </div>
        <div v-else-if="isAuthenticated && user" class="ion-text-center">
          <ion-avatar style="margin: 0 auto; width: 80px; height: 80px;">
            <img :src="user.picture" :alt="user.name" />
          </ion-avatar>
          <h2>{{ user.name }}</h2>
          <p>{{ user.email }}</p>
        </div>
      </template>

      <script setup lang="ts">
      import { useAuth0 } from '@auth0/auth0-vue'
      import { IonAvatar } from '@ionic/vue'

      const { user, isAuthenticated, isLoading } = useAuth0()
      </script>
      ```

      ```vue src/views/HomePage.vue expandable lines theme={null}
      <template>
        <ion-page>
          <ion-header>
            <ion-toolbar>
              <ion-title>Auth0 + Ionic Vue</ion-title>
            </ion-toolbar>
          </ion-header>

          <ion-content class="ion-padding ion-text-center">
            <div v-if="isLoading">
              <ion-spinner />
              <p>Loading...</p>
            </div>

            <div v-else-if="error">
              <h2>Oops!</h2>
              <p>{{ error.message }}</p>
            </div>

            <div v-else-if="isAuthenticated">
              <div style="margin-bottom: 1rem;">
                <UserProfile />
              </div>
              <LogoutButton />
            </div>

            <div v-else>
              <h2>Welcome</h2>
              <p>Get started by signing in to your account</p>
              <LoginButton />
            </div>
          </ion-content>
        </ion-page>
      </template>

      <script setup lang="ts">
      import {
        IonPage,
        IonHeader,
        IonToolbar,
        IonTitle,
        IonContent,
        IonSpinner,
      } from '@ionic/vue'
      import { useAuth0 } from '@auth0/auth0-vue'
      import LoginButton from '../components/LoginButton.vue'
      import LogoutButton from '../components/LogoutButton.vue'
      import UserProfile from '../components/UserProfile.vue'

      const { isAuthenticated, isLoading, error } = useAuth0()
      </script>
      ```

      ```vue src/App.vue expandable lines theme={null}
      <template>
        <ion-app>
          <ion-router-outlet />
        </ion-app>
      </template>

      <script setup lang="ts">
      import { IonApp, IonRouterOutlet } from '@ionic/vue'
      import { useAuth0 } from '@auth0/auth0-vue'
      import { App as CapApp } from '@capacitor/app'
      import { Browser } from '@capacitor/browser'

      const { handleRedirectCallback } = useAuth0()

      CapApp.addListener('appUrlOpen', async ({ url }) => {
        if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
          await handleRedirectCallback(url)
        }
        await Browser.close()
      })
      </script>
      ```
    </AuthCodeGroup>
  </Step>

  <Step title="Lancez votre application" stepNumber={6}>
    Commencez par tester dans le navigateur :

    ```shellscript theme={null}
    ionic serve
    ```

    <Warning>
      Lorsque vous exécutez l’application dans le navigateur avec `ionic serve`, la redirection à l’aide d’un schéma d’URL personnalisé ne fonctionnera pas, car les navigateurs ne prennent pas en charge les schémas d’URL personnalisés. Pour faire des tests dans le navigateur, remplacez temporairement `redirect_uri` par `http://localhost:8100` dans `src/main.ts`, puis ajoutez `http://localhost:8100` à **Allowed Callback URLs** et à **Allowed Logout URLs** de votre application Auth0 dans le Dashboard. N’oubliez pas de rétablir cette modification avant de générer l’application native.
    </Warning>

    Pour exécuter l’application sur un appareil ou dans un simulateur, ajoutez d’abord les plateformes natives :

    ```shellscript theme={null}
    npx cap add ios
    npx cap add android
    ```

    Ensuite, compilez, synchronisez et exécutez :

    <CodeGroup>
      ```shellscript iOS theme={null}
      ionic build && npx cap sync && npx cap run ios
      ```

      ```shellscript Android theme={null}
      ionic build && npx cap sync && npx cap run android
      ```
    </CodeGroup>

    <Info>
      Vous devez ajouter les plateformes natives avec `npx cap add` avant de pouvoir les exécuter. Cette opération ne doit être effectuée qu’une seule fois par plateforme. Assurez-vous d’abord d’avoir enregistré le [schéma d’URL personnalisé](#custom-url-scheme-setup) pour votre plateforme.
    </Info>
  </Step>
</Steps>

<Check>
  **Vérification**

  Vous devriez maintenant avoir une expérience de connexion Auth0 entièrement fonctionnelle dans votre application Ionic Vue, avec la connexion, la déconnexion et les renseignements du profil utilisateur.
</Check>

***

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

<Accordion title="Configuration d’un schéma d’URL personnalisé">
  Enregistrez le schéma d’URL personnalisé de votre application afin que le système d’exploitation puisse rediriger l’URL de rappel OAuth vers votre application après l’authentification.

  ### iOS

  Enregistrez votre schéma d’URL personnalisé dans votre `ios/App/App/Info.plist` :

  ```xml theme={null}
  <key>CFBundleURLTypes</key>
  <array>
    <dict>
      <key>CFBundleURLSchemes</key>
      <array>
        <string>YOUR_PACKAGE_ID</string>
      </array>
    </dict>
  </array>
  ```

  Remplacez `YOUR_PACKAGE_ID` par le `appId` de votre `capacitor.config.ts`. Pour en savoir plus, consultez [Defining a Custom URL Scheme](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app).

  ### Android

  Ajoutez un filtre d’intention dans votre `android/app/src/main/AndroidManifest.xml`, à l’intérieur de la balise principale `<activity>` :

  ```xml theme={null}
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="YOUR_PACKAGE_ID" />
  </intent-filter>
  ```

  Pour en savoir plus, consultez [Create Deep Links to App Content](https://developer.android.com/training/app-links/deep-linking).

  <Tip>
    Après avoir modifié les fichiers du projet natif, exécutez `npx cap sync` pour vous assurer que vos changements sont appliqués.
  </Tip>
</Accordion>

<Accordion title="Protection des routes avec Vue Router">
  Utilisez le `authGuard` intégré de l’Auth0 Vue SDK pour protéger les routes qui nécessitent une authentification :

  ```typescript src/router/index.ts theme={null}
  import { createRouter, createWebHistory } from '@ionic/vue-router'
  import { authGuard } from '@auth0/auth0-vue'
  import HomePage from '../views/HomePage.vue'
  import ProfilePage from '../views/ProfilePage.vue'

  const routes = [
    {
      path: '/',
      name: 'Home',
      component: HomePage,
    },
    {
      path: '/profile',
      name: 'Profile',
      component: ProfilePage,
      beforeEnter: authGuard,
    },
  ]

  const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes,
  })

  export default router
  ```

  Le `authGuard` redirige automatiquement les utilisateurs non authentifiés vers la page Auth0 Universal Login. Après la connexion, ils sont renvoyés vers la route initialement demandée.
</Accordion>

<Accordion title="Appeler des API protégées">
  Configurez le paramètre `audience` dans votre configuration `createAuth0` pour demander des jetons d’accès pour votre API :

  ```typescript src/main.ts theme={null}
  app.use(
    createAuth0({
      domain: '{yourDomain}',
      clientId: '{yourClientId}',
      useRefreshTokens: true,
      useRefreshTokensFallback: false,
      authorizationParams: {
        redirect_uri,
        audience: 'YOUR_API_IDENTIFIER',
      },
    })
  )
  ```

  Utilisez ensuite `getAccessTokenSilently` dans vos composants pour récupérer des jetons et effectuer des appels d’API authentifiés :

  ```vue src/components/ApiCall.vue theme={null}
  <template>
    <ion-button @click="callApi" :disabled="loading">
      {{ loading ? 'Calling...' : 'Call Protected API' }}
    </ion-button>
    <pre v-if="response">{{ JSON.stringify(response, null, 2) }}</pre>
  </template>

  <script setup lang="ts">
  import { ref } from 'vue'
  import { useAuth0 } from '@auth0/auth0-vue'
  import { IonButton } from '@ionic/vue'

  const { getAccessTokenSilently } = useAuth0()
  const response = ref(null)
  const loading = ref(false)

  const callApi = async () => {
    try {
      loading.value = true
      const token = await getAccessTokenSilently()

      const res = await fetch('https://your-api.com/endpoint', {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      })

      response.value = await res.json()
    } catch (error) {
      console.error('API call failed:', error)
    } finally {
      loading.value = false
    }
  }
  </script>
  ```

  <Tip>
    La méthode `getAccessTokenSilently` récupère le jeton depuis le cache ou l’actualise automatiquement au moyen du jeton d’actualisation, au besoin.
  </Tip>
</Accordion>

<Accordion title="Utilisation du modèle defineComponent">
  Si vous préférez le modèle explicite `defineComponent` à `<script setup>`, voici à quoi ressemble le composant LoginButton avec cette approche :

  ```vue src/components/LoginButton.vue theme={null}
  <template>
    <ion-button @click="login" expand="block">Log in</ion-button>
  </template>

  <script lang="ts">
  import { defineComponent } from 'vue'
  import { useAuth0 } from '@auth0/auth0-vue'
  import { Browser } from '@capacitor/browser'
  import { IonButton } from '@ionic/vue'

  export default defineComponent({
    components: { IonButton },
    setup() {
      const { loginWithRedirect } = useAuth0()

      const login = async () => {
        await loginWithRedirect({
          openUrl: (url: string) =>
            Browser.open({ url, windowName: '_self' }),
        })
      }

      return { login }
    },
  })
  </script>
  ```

  Le modèle `defineComponent` exige d’enregistrer explicitement les composants enfants et de retourner les valeurs depuis la fonction `setup()`. Les deux modèles sont entièrement pris en charge par le Auth0 Vue SDK.
</Accordion>

<Accordion title="Problèmes courants et solutions">
  ### Erreur de non-correspondance de l’URL de rappel

  **Solution :** Vérifiez que l’URL de rappel dans votre Auth0 Dashboard correspond exactement à l’URL construite dans votre application. Assurez-vous que `YOUR_PACKAGE_ID` correspond au champ `appId` dans votre fichier `capacitor.config.ts`.

  ### Erreur « PKCE not allowed »

  **Correctif :**

  1. Accédez à Auth0 Dashboard > Applications > Your Application
  2. Remplacez **Application Type** par **Native**
  3. Définissez **Token Endpoint Authentication Method** sur `None`
  4. Enregistrez les modifications et réessayez

  ### SSO ne fonctionne pas sur iOS

  Le Plugin Browser de Capacitor utilise `SFSafariViewController`, qui ne partage pas les cookie avec Safari sur iOS 11+. Si vous avez besoin du SSO, utilisez un Plugin compatible qui repose sur [ASWebAuthenticationSession](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession).

  ### Le login fonctionne, mais l’utilisateur reste non authentifié après le redémarrage de l’application

  Activez `cacheLocation: 'localstorage'` dans la configuration `createAuth0` pour enregistrer les jetons entre les redémarrages de l’application. Gardez à l’esprit les [implications de sécurité](https://auth0.com/docs/libraries/auth0-single-page-app-sdk#change-storage-options). Le SDK prend aussi en charge des [implémentations de cache personnalisées](https://github.com/auth0/auth0-spa-js/blob/master/EXAMPLES.md#creating-a-custom-cache) pour un stockage plus sécurisé.

  ### Le navigateur ne se ferme pas après le login

  Assurez-vous d’appeler `Browser.close()` dans l’écouteur de l’événement `appUrlOpen` de votre composant `App.vue`. Sur Android, `Browser.close()` est un no-op; le navigateur se ferme donc automatiquement.

  ### La page de connexion s’ouvre dans l’application de navigateur par défaut de l’appareil

  Si la page de connexion s’ouvre dans Safari ou Chrome au lieu d’un navigateur intégré à l’application, assurez-vous de transmettre le callback `openUrl` à `loginWithRedirect` et à `logout`. Sinon, le SDK utilise `window.location.href` par défaut, ce qui redirige l’application au complet.
</Accordion>
