> ## 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 l’authentification à votre application Nuxt.js

> Ce guide explique comment intégrer Auth0, ajouter l’authentification et afficher les renseignements du profil de l’utilisateur dans une application à page unique (SPA) qui utilise Nuxt.js, à l’aide du SDK Auth0 Nuxt.js.

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

<HowToSchema />

<Callout icon="pencil" color="#FFC107" iconType="solid">
  Ce guide de démarrage rapide est actuellement en **bêta**. Nous aimerions connaître votre avis!
</Callout>

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

  **Installer :**

  ```bash theme={null}
  npx skills add https://github.com/auth0/agent-skills --skill auth0-nuxt
  ```

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

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

  Votre assistant d’IA créera automatiquement votre application Auth0, récupérera les identifiants, installera `@auth0/auth0-nuxt`, configurera le module et mettra en place vos routes. [Documentation complète sur les agent skills →](/fr-CA/docs/quickstart/agent-skills)
</Accordion>

<Note>
  **Prérequis :** Avant de commencer, assurez-vous d’avoir installé ce qui suit :

  * **[Node.js](https://nodejs.org/en/download)** 20 LTS ou une version ultérieure
  * **[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/)** - Requis pour configurer Auth0 CLI

  **Compatibilité des versions de Nuxt :** Ce guide de démarrage rapide fonctionne avec **Nuxt 3.x** sans configuration supplémentaire. Pour **Nuxt 4.x**, assurez-vous d’utiliser Nuxt 4.2+.
</Note>

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

Ce guide de démarrage rapide explique comment ajouter l’authentification Auth0 à une application Nuxt.js. Vous créerez une application monopage sécurisée avec des fonctionnalités de connexion, de déconnexion et de profil utilisateur à l’aide du SDK Nuxt d’Auth0.

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

    ```shellscript theme={null}
    npx nuxi@latest init auth0-nuxt-app
    ```

    Ouvrez le projet

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

  <Step title="Installez le SDK Nuxt d’Auth0" stepNumber={2}>
    ```shellscript theme={null}
    npm add @auth0/auth0-nuxt && npm install
    ```
  </Step>

  <Step title="Configurez votre application Auth0" stepNumber={3}>
    Ensuite, créez une nouvelle application sur votre locataire Auth0 et ajoutez les variables d'environnement à votre projet.

    Vous pouvez effectuer cette opération automatiquement en exécutant une commande CLI ou manuellement via le tableau de bord :

    <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` :

        <CodeGroup>
          ```shellscript Mac theme={null}
          AUTH0_APP_NAME="My Nuxt App" && brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && auth0 apps create -n "${AUTH0_APP_NAME}" -t regular -c http://localhost:3000/auth/callback -l http://localhost:3000 -o http://localhost:3000 --reveal-secrets --json > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && CLIENT_SECRET=$(jq -r '.client_secret' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && echo "NUXT_AUTH0_DOMAIN=${DOMAIN}" > .env && echo "NUXT_AUTH0_CLIENT_ID=${CLIENT_ID}" >> .env && echo "NUXT_AUTH0_CLIENT_SECRET=${CLIENT_SECRET}" >> .env && echo "NUXT_AUTH0_SESSION_SECRET=$(openssl rand -hex 64)" >> .env && echo "NUXT_AUTH0_APP_BASE_URL=http://localhost:3000" >> .env && rm auth0-app-details.json && echo ".env file created with your Auth0 details:" && cat .env
          ```

          ```shellscript Windows theme={null}
          $AppName = "My Nuxt App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t regular -c http://localhost:3000/auth/callback -l http://localhost:3000 -o http://localhost:3000 --reveal-secrets --json | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $ClientSecret = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_secret; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; Set-Content -Path .env -Value "NUXT_AUTH0_DOMAIN=$Domain"; Add-Content -Path .env -Value "NUXT_AUTH0_CLIENT_ID=$ClientId"; Add-Content -Path .env -Value "NUXT_AUTH0_CLIENT_SECRET=$ClientSecret"; $SessionSecret = -join ((1..128) | ForEach {'{0:X}' -f (Get-Random -Max 16)}); Add-Content -Path .env -Value "NUXT_AUTH0_SESSION_SECRET=$SessionSecret"; Add-Content -Path .env -Value "NUXT_AUTH0_APP_BASE_URL=http://localhost:3000"; Remove-Item auth0-app-details.json; Write-Output ".env file created with your Auth0 details:"; Get-Content .env
          ```
        </CodeGroup>
      </Tab>

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

        ```shellscript .env theme={null}
        NUXT_AUTH0_DOMAIN=YOUR_AUTH0_APP_DOMAIN
        NUXT_AUTH0_CLIENT_ID=YOUR_AUTH0_APP_CLIENT_ID
        NUXT_AUTH0_CLIENT_SECRET=YOUR_AUTH0_APP_CLIENT_SECRET
        NUXT_AUTH0_SESSION_SECRET=YOUR_SESSION_SECRET
        NUXT_AUTH0_APP_BASE_URL=http://localhost:3000
        ```

        1. Accédez au [Auth0 Dashboard ](https://manage.auth0.com/dashboard/)
        2. Cliquez sur **Applications**  > **Applications** > **Create Application**
        3. Dans la fenêtre contextuelle, entrez un nom pour votre application, sélectionnez `Regular Web Application` comme type d’application, puis cliquez sur **Create**
        4. Passez à l’onglet **Settings** de la page des détails de l’application
        5. Remplacez les valeurs du fichier `.env` par celles de **Domaine**, **ID client** et **Secret client** du tableau de bord
        6. Générez un secret de session en exécutant : `openssl rand -hex 64`, puis utilisez-le pour `NUXT_AUTH0_SESSION_SECRET`

        Enfin, dans l’onglet **Settings** de la page des détails de votre application, configurez les URL suivantes :

        **Allowed Callback URLs:**

        ```
        http://localhost:3000/auth/callback
        ```

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

        ```
        http://localhost:3000
        ```

        **Origines Web autorisées :**

        ```
        http://localhost:3000
        ```

        <Info>
          **Allowed Callback URLs** est une mesure de sécurité essentielle pour garantir que les utilisateurs sont redirigés en toute sécurité 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.

          **Allowed Logout URLs** est essentiel pour offrir une expérience utilisateur 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.

          **Allowed Web Origins** est essentiel pour l’authentification silencieuse. Sans cela, les utilisateurs seront déconnectés lorsqu’ils actualiseront la page ou reviendront plus tard dans votre application.
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configurer le module Nuxt Auth0" stepNumber={4}>
    ```typescript nuxt.config.ts {3,4,5,6,7,8,9,10,11,12,13} lines theme={null}
    export default defineNuxtConfig({
      devtools: { enabled: true },
      modules: ['@auth0/auth0-nuxt'],
      runtimeConfig: {
        auth0: {
          domain: process.env.NUXT_AUTH0_DOMAIN,
          clientId: process.env.NUXT_AUTH0_CLIENT_ID,
          clientSecret: process.env.NUXT_AUTH0_CLIENT_SECRET,
          sessionSecret: process.env.NUXT_AUTH0_SESSION_SECRET,
          appBaseUrl: process.env.NUXT_AUTH0_APP_BASE_URL,
        },
      },
    })
    ```
  </Step>

  <Step title="Créer des composants de connexion, de déconnexion et de profil" stepNumber={5}>
    Créer des fichiers

    ```shellscript theme={null}
    mkdir -p app/components && touch app/components/LoginButton.vue && touch app/components/LogoutButton.vue && touch app/components/UserProfile.vue
    ```

    Et ajoutez les extraits de code suivants

    <CodeGroup>
      ```vue app/components/LoginButton.vue expandable lines theme={null}
      <template>
       <a 
          href="/auth/login" 
          class="button login"
        >
          Log In
        </a>
      </template>

      <style scoped>
      .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:not(:disabled) {
        background-color: #4299e1;
        transform: translateY(-5px) scale(1.03);
        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
      }

      .button:disabled {
        opacity: 0.7;
        cursor: not-allowed;
        transform: none;
      }
      </style>
      ```

      ```vue app/components/LogoutButton.vue expandable lines theme={null}
      <template>
       <a
          href="/auth/logout"
          class="button logout"
        >
          Log Out
        </a>
      </template>

      <style scoped>
      .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.logout {
        background-color: #fc8181;
        color: #1a1e27;
      }

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

      .button:disabled {
        opacity: 0.7;
        cursor: not-allowed;
        transform: none;
      }
      </style>
      ```

      ```vue app/components/UserProfile.vue expandable lines theme={null}
      <template>
        <div v-if="pending" class="loading-text">
          Loading profile...
        </div>
        <div v-else-if="user" class="profile-container">
          <img 
            :src="user.picture || placeholderImage" 
            :alt="user.name || 'User'" 
            class="profile-picture"
            @error="handleImageError"
          />
          <div class="profile-info">
            <div class="profile-name">
              {{ user.name }}
            </div>
            <div class="profile-email">
              {{ user.email }}
            </div>
          </div>
        </div>
      </template>

      <script setup lang="ts">
      const user = useUser()
      const pending = ref(false)

      const placeholderImage = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='50' fill='%2363b3ed'/%3E%3Cpath d='M50 45c7.5 0 13.64-6.14 13.64-13.64S57.5 17.72 50 17.72s-13.64 6.14-13.64 13.64S42.5 45 50 45zm0 6.82c-9.09 0-27.28 4.56-27.28 13.64v3.41c0 1.88 1.53 3.41 3.41 3.41h47.74c1.88 0 3.41-1.53 3.41-3.41v-3.41c0-9.08-18.19-13.64-27.28-13.64z' fill='%23fff'/%3E%3C/svg%3E`

      function handleImageError(e: Event) {
        const target = e.target as HTMLImageElement
        target.src = placeholderImage
      }

      // Simuler l'état de chargement pour une meilleure expérience utilisateur
      onMounted(() => {
        pending.value = true
        nextTick(() => {
          pending.value = false
        })
      })
      </script>

      <style scoped>
      .profile-container {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 1rem;
      }

      .profile-picture {
        width: 110px;
        height: 110px;
        border-radius: 50%;
        object-fit: cover;
        border: 3px solid #63b3ed;
        transition: transform 0.3s ease-in-out;
      }

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

      .profile-info {
        text-align: center;
      }

      .profile-name {
        font-size: 2rem;
        font-weight: 600;
        color: #f7fafc;
        margin-bottom: 0.5rem;
      }

      .profile-email {
        font-size: 1.15rem;
        color: #a0aec0;
      }

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

      @keyframes pulse {
        0%, 100% { opacity: 1; }
        50% { opacity: 0.6; }
      }
      </style>
      ```

      ```vue app.vue expandable lines theme={null}
      <template>
        <div class="app-container">
          <div class="main-card-wrapper">
            <img 
              src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png" 
              alt="Auth0 Logo" 
              class="auth0-logo"
            />
            <h1 class="main-title">Welcome to Auth0 Nuxt</h1>

            <div v-if="user" class="logged-in-section">
              <div class="logged-in-message">✅ Successfully authenticated!</div>
              <h2 class="profile-section-title">Your Profile</h2>
              <div class="profile-card">
                <UserProfile />
              </div>
              <LogoutButton />
            </div>

            <div v-else class="action-card">
              <p class="action-text">Get started by signing in to your account</p>
              <LoginButton />
            </div>
          </div>
        </div>
      </template>


      <script setup lang="ts">
      const user = useUser()
      </script>

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

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

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

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

        .auth0-logo {
          width: 120px;
        }
      }
      </style>
      ```
    </CodeGroup>
  </Step>

  <Step title="Lancez votre application" stepNumber={6}>
    ```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 s’exécute sur votre [localhost](http://localhost:3000/)
</Check>
