# E-Mails mit Nuxt senden

> Senden Sie E-Mails aus einer Server-API-Route von Nuxt mit dem Node.js-SDK von Emailit, halten Sie den Schlüssel in der privaten runtimeConfig und verifizieren Sie Webhooks mit h3.

Diese Anleitung zeigt, wie Sie E-Mails aus einer Nuxt-3-App senden. Sie rufen Emailit aus einer Server-API-Route auf, halten den API-Schlüssel in der privaten `runtimeConfig` und verifizieren Webhooks mit Hilfsfunktionen von h3.

## Voraussetzungen

- Nuxt 3 mit einem Server-Preset für Node.js 18 oder neuer.
- Eine [verifizierte Versanddomain](/de/docs/domains/add-a-domain/), zum Beispiel `acme.com`.
- Ein [API-Schlüssel](/de/docs/developers/api-keys/). Ein reiner Sende-Schlüssel, der auf Ihre Domain beschränkt ist, genügt.
- Solange Ihr Workspace keinen [Produktionszugang](/de/docs/workspaces/production-access/) hat, können Sie nur an die Konto-E-Mail-Adressen von Workspace-Mitgliedern senden.

## SDK installieren

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

## API-Schlüssel konfigurieren

Deklarieren Sie private Schlüssel in der Runtime-Konfiguration. Schlüssel außerhalb von `public` sind nur auf dem Server verfügbar:

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

Nuxt befüllt sie aus Umgebungsvariablen mit dem Präfix `NUXT_`:

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

> **Schlüssel nicht in runtimeConfig.public ablegen:** Werte unter `runtimeConfig.public` werden an den Browser gesendet. Legen Sie den API-Schlüssel nie dort ab und rufen Sie Emailit nie aus einer Komponente oder Seite auf.

Fügen Sie eine kleine Hilfsfunktion hinzu. Dateien in `server/utils` werden in Server-Routen automatisch importiert:

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

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

Wenn TypeScript eine fehlende Deklaration für `@emailit/node` meldet, fügen Sie `declare module '@emailit/node';` in eine `.d.ts`-Datei in Ihrem Projekt ein.

## E-Mail senden

Erstellen Sie eine Server-API-Route. Diese Route für ein Kontaktformular sendet an eine feste interne Adresse, sodass Besucher sie nicht nutzen können, um beliebigen Personen E-Mails zu schicken:

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

Rufen Sie sie aus einer Seite oder Komponente mit `$fetch` auf:

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

Um statt Inline-Inhalt eine gespeicherte Vorlage zu senden, übergeben Sie `template` (einen Alias oder eine `tem_`-ID) und `variables`. Siehe [Vorlagen](/de/docs/templates/) und [E-Mail senden](/de/docs/api-reference/emails/send/).

## Alternativ per SMTP senden

Wenn Sie SMTP bevorzugen, verwenden Sie Nodemailer in einer Server-Route. SMTP erfordert ein Node.js-Server-Preset; Edge- und Worker-Presets können keine SMTP-Verbindungen öffnen, verwenden Sie dort also die API.

```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 },
  });
}
```

Rufen Sie dann in einer Route `await mailer().sendMail({ from, to, subject, html })` auf. Weitere Ports finden Sie unter [SMTP-Einstellungen](/de/docs/smtp/settings/).

## Webhooks empfangen

[Erstellen Sie einen Webhook](/de/docs/webhooks/set-up/), der auf `https://your-app.com/api/webhooks/emailit` zeigt. Verifizieren Sie die Signatur anhand des unveränderten Bodys und parsen Sie dann das Array der Events:

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

Geben Sie innerhalb von 30 Sekunden einen `2xx`-Status zurück; bei anderen Antworten wird die Anfrage wiederholt. Siehe [Anfragesignatur](/de/docs/webhooks/request-signature/).

## Tipps für den Produktivbetrieb

- **Secrets beim Hoster hinterlegen.** Konfigurieren Sie `NUXT_EMAILIT_API_KEY` in den Umgebungseinstellungen Ihres Hosting-Anbieters, statt eine `.env`-Datei auszuliefern.
- **Vor dem Senden validieren.** Übernehmen Sie einen Empfänger nur dann aus dem Browser, wenn es die eigene Adresse des angemeldeten Nutzers ist, und begrenzen Sie die Anfragerate öffentlicher Routen. Jede E-Mail kostet Credits und zählt gegen Ihre [Versandlimits](/de/docs/limits/).
- **Getrennte Schlüssel pro Umgebung verwenden**, damit Sie einen Preview-Schlüssel widerrufen können, ohne die Produktion zu berühren.

## Nächste Schritte

  - [Anleitung für Node.js](/de/docs/frameworks/nodejs/): Fehlerbehandlung und Details zu Nodemailer.
  - [E-Mails per API senden](/de/docs/email-api/send-email/): Anhänge, Planung und Tracking.
  - [Webhook-Event-Typen](/de/docs/webhooks/event-types/): Alle Events und ihre Payloads.
  - [API-Schlüssel](/de/docs/developers/api-keys/): Scopes, Domain-Beschränkungen und Rotation.

---
Quelle: https://emailit.com/de/docs/frameworks/nuxt/
