# Envoyer des e-mails avec Nuxt

> Envoyez des e-mails depuis une route d’API serveur Nuxt avec le SDK Node.js d’Emailit, gardez la clé dans le runtimeConfig privé et vérifiez les webhooks avec h3.

Ce guide montre comment envoyer des e-mails depuis une application Nuxt 3. Vous appelez Emailit depuis une route d’API serveur, gardez la clé API dans le `runtimeConfig` privé et vérifiez les webhooks avec les fonctions utilitaires de h3.

## Prérequis

- Nuxt 3 avec un preset serveur Node.js 18 ou version ultérieure.
- Un [domaine d’envoi vérifié](/fr/docs/domains/add-a-domain/), par exemple `acme.com`.
- Une [clé API](/fr/docs/developers/api-keys/). Une clé Sending Only limitée à votre domaine suffit.
- Tant que votre espace de travail n’a pas l’[accès production](/fr/docs/workspaces/production-access/), vous ne pouvez envoyer qu’aux adresses e-mail des comptes des membres de l’espace de travail.

## Installer le SDK

```bash
npm install @emailit/node
```

## Configurer votre clé API

Déclarez des clés de configuration d’exécution privées. Les clés situées hors de `public` ne sont disponibles que sur le serveur :

```typescript title="nuxt.config.ts"
  runtimeConfig: {
    emailitApiKey: '',
    emailitWebhookSecret: '',
  },
});
```

Nuxt les renseigne à partir des variables d’environnement préfixées par `NUXT_` :

```bash title=".env"
NUXT_EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••
NUXT_EMAILIT_WEBHOOK_SECRET=whsec_••••••••
```

> **Ne mettez pas la clé dans runtimeConfig.public:** Les valeurs placées sous `runtimeConfig.public` sont envoyées au navigateur. N’y mettez jamais la clé API, et n’appelez jamais Emailit depuis un composant ou une page.

Ajoutez une petite fonction utilitaire. Les fichiers de `server/utils` sont importés automatiquement dans les routes serveur :

```typescript title="server/utils/emailit.ts"

  return new Emailit(useRuntimeConfig(event).emailitApiKey);
}
```

Si TypeScript signale une déclaration manquante pour `@emailit/node`, ajoutez `declare module '@emailit/node';` à un fichier `.d.ts` de votre projet.

## Envoyer un e-mail

Créez une route d’API serveur. Cette route de formulaire de contact envoie à une adresse interne fixe : les visiteurs ne peuvent donc pas l’utiliser pour envoyer des e-mails à n’importe qui :

```typescript title="server/api/contact.post.ts"
  const { email, message } = await readBody(event);

  if (typeof email !== 'string' || typeof message !== 'string' || !email.includes('@')) {
    throw createError({ statusCode: 400, statusMessage: 'Invalid input' });
  }

  const sent = await emailitClient(event).emails.send({
    from: 'Acme website <website@acme.com>',
    to: 'support@acme.com',
    reply_to: email,
    subject: 'New contact form message',
    text: message,
  });

  return { id: sent.id };
});
```

Appelez-la depuis une page ou un composant avec `$fetch` :

```vue title="pages/contact.vue"
<script setup lang="ts">
const email = ref('');
const message = ref('');
const sent = ref(false);

async function submit() {
  await $fetch('/api/contact', {
    method: 'POST',
    body: { email: email.value, message: message.value },
  });
  sent.value = true;
}
</script>

<template>
  <form @submit.prevent="submit">
    <input v-model="email" type="email" required />
    <textarea v-model="message" required />
    <button type="submit">Send</button>
    <p v-if="sent">Thanks, we'll be in touch.</p>
  </form>
</template>
```

Pour envoyer un modèle enregistré plutôt qu’un contenu en ligne, transmettez `template` (un alias ou un ID `tem_`) et `variables`. Consultez [Modèles](/fr/docs/templates/) et [Envoyer un e-mail](/fr/docs/api-reference/emails/send/).

## Envoyer plutôt via SMTP

Si vous préférez le SMTP, utilisez Nodemailer dans une route serveur. Le SMTP nécessite un preset serveur Node.js ; les presets edge et worker ne peuvent pas ouvrir de connexions SMTP : utilisez l’API dans ce cas.

```typescript title="server/utils/mailer.ts"

  return nodemailer.createTransport({
    host: 'smtp.emailit.com',
    port: 587,
    secure: false,
    requireTLS: true,
    auth: { user: 'emailit', pass: useRuntimeConfig().emailitApiKey },
  });
}
```

Appelez ensuite `await mailer().sendMail({ from, to, subject, html })` depuis une route. Pour les autres ports, consultez [Paramètres SMTP](/fr/docs/smtp/settings/).

## Recevoir des webhooks

[Créez un webhook](/fr/docs/webhooks/set-up/) qui pointe vers `https://your-app.com/api/webhooks/emailit`. Vérifiez la signature à partir du corps brut, puis analysez le tableau d’événements :

```typescript title="server/api/webhooks/emailit.post.ts"

  const rawBody = (await readRawBody(event)) ?? '';
  const signature = getHeader(event, 'x-emailit-signature') ?? '';
  const timestamp = getHeader(event, 'x-emailit-timestamp') ?? '';
  const secret = useRuntimeConfig(event).emailitWebhookSecret;

  const age = Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp));
  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
  const valid =
    Number.isFinite(age) &&
    age <= 300 &&
    expected.length === signature.length &&
    timingSafeEqual(Buffer.from(expected), Buffer.from(signature));

  if (!valid) {
    throw createError({ statusCode: 401, statusMessage: 'Invalid signature' });
  }

  const events = JSON.parse(rawBody) as Array<{ event_id: string; type: string; data: { object: any } }>;
  for (const item of events) {
    if (item.type === 'email.complained') {
      // Stop emailing item.data.object.to
    }
  }

  return { received: events.length };
});
```

Renvoyez un `2xx` dans les 30 secondes ; pour toute autre réponse, Emailit réessaie. Consultez [Signature des requêtes](/fr/docs/webhooks/request-signature/).

## Conseils pour la production

- **Définissez les secrets chez votre hébergeur.** Configurez `NUXT_EMAILIT_API_KEY` dans les paramètres d’environnement de votre hébergeur plutôt que de livrer un fichier `.env`.
- **Validez avant d’envoyer.** N’acceptez un destinataire depuis le navigateur que s’il s’agit de l’adresse de l’utilisateur connecté, et limitez le débit des routes publiques. Chaque e-mail coûte des crédits et compte dans vos [limites d’envoi](/fr/docs/limits/).
- **Utilisez des clés distinctes par environnement** pour pouvoir révoquer une clé de prévisualisation sans toucher à la production.

## Étapes suivantes

  - [Guide Node.js](/fr/docs/frameworks/nodejs/): Gestion des erreurs et détails sur Nodemailer.
  - [Envoyer des e-mails avec l’API](/fr/docs/email-api/send-email/): Pièces jointes, programmation et suivi.
  - [Types d’événements webhook](/fr/docs/webhooks/event-types/): Tous les événements et leur payload.
  - [Clés API](/fr/docs/developers/api-keys/): Portées, limitation à un domaine et rotation.

---
Source: https://emailit.com/fr/docs/frameworks/nuxt/
