Kontaktformular in React Native (und Expo) erstellen, das E-Mails versendet
Ein React-Native-Kontaktformular, das Ihnen jede Nachricht per E-Mail schickt – mit Sendestatus, Bot-Schutz und ohne Backend. Funktioniert mit Expo und reinem React Native.
Aktualisiert:
Sie fügen einer React-Native- oder Expo-App mit dem Paket @frontmail/react-native ein
Kontaktformular hinzu: einen Provider, einen useSendEmail-Hook, der den Sendestatus verfolgt,
und eine fertige Turnstile-Komponente gegen Bots. Die E-Mail geht über Ihr eigenes Postfach raus.
Sie brauchen: ein kostenloses Frontmail-Konto, ein Expo- oder React-Native-Projekt und etwa zehn Minuten.
1. Postfach verbinden und Vorlage anlegen
- E-Mail-Dienste → Dienst hinzufügen: Verbinden Sie Gmail, Outlook, SMTP oder einen Transaktions-Anbieter, aktivieren Sie Als Standard festlegen, dann Prüfen & speichern.
- Vorlagen → Aus der Galerie → Kontaktformular → Vorlage verwenden.
Pflichtparameter:
name,email,message; optional:phone,topic. - Kopieren Sie die Vorlagen-ID (
tpl_…) aus dem Tab Snippets.
2. Mobile Apps erlauben
- Sicherheit → Mobile Apps → Mobile Apps erlauben → Speichern. Apps senden keinen
Origin-Header, ohne diesen Schalter antwortet die API daher mitorigin_not_allowed. - Vorlage → Einstellungen → Schutz → CAPTCHA verlangen (Turnstile). Die App nutzt das gemeinsame Turnstile-Widget von Frontmail; Cloudflare-Schlüssel brauchen Sie nicht.
3. Installieren
npx expo install @frontmail/react-native @react-native-async-storage/async-storage react-native-webview
In einem reinen React-Native-Projekt installieren Sie dieselben Pakete mit npm i und führen
danach npx pod-install aus.
4. Formular bauen
import { useRef, useState } from 'react';
import { Button, Text, TextInput, View } from 'react-native';
import { FrontmailProvider, TurnstileWebView, useSendEmail, type TurnstileWebViewHandle } from '@frontmail/react-native';
const options = { publicKey: 'pk_…' }; // keep the object stable
export default function App() {
return (
<FrontmailProvider options={options}>
<ContactForm />
</FrontmailProvider>
);
}
function ContactForm() {
const { send, status, error } = useSendEmail(null, 'tpl_…'); // null = default service
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [message, setMessage] = useState('');
const [token, setToken] = useState<string>();
const turnstile = useRef<TurnstileWebViewHandle>(null);
const onSend = async () => {
await send({ name, email, message }, { turnstileToken: token });
setToken(undefined);
turnstile.current?.reset(); // a token works only once
};
if (status === 'sent' || status === 'held') return <Text>Thank you! We’ll get back to you soon.</Text>;
return (
<View style={{ gap: 12, padding: 16 }}>
<TextInput placeholder="Name" value={name} onChangeText={setName} />
<TextInput placeholder="Email" value={email} onChangeText={setEmail} keyboardType="email-address" autoCapitalize="none" />
<TextInput placeholder="Message" value={message} onChangeText={setMessage} multiline />
<TurnstileWebView ref={turnstile} onToken={setToken} />
<Button title="Send" disabled={!token || status === 'sending'} onPress={onSend} />
{error && <Text>{error.message}</Text>}
</View>
);
}
send wirft nie eine Ausnahme: Es liefert das Ergebnis oder undefined, und status wechselt
von idle zu sending und dann zu sent, held oder error. Wiederholungen nach
Netzwerkfehlern verwenden denselben Idempotenzschlüssel – wer im Zug sitzt, schickt Ihnen dieselbe
Nachricht also nie zweimal.
5. Testen
Starten Sie die App (npx expo start), füllen Sie das Formular aus und tippen Sie auf Send.
Die E-Mail landet in Ihrem Postfach und im Dashboard unter Verlauf.
origin_not_allowed– Mobile Apps erlauben ist ausgeschaltet oder nicht gespeichert.captcha_required– die Turnstile-Prüfung ist noch nicht fertig; der Button bleibt deaktiviert, bis ein Token vorliegt.invalid_template_params– ein Pflichtfeld ist leer oder die E-Mail-Adresse ungültig.
heldbedeutet, dass die Nachricht angenommen wurde, während Ihre Credits aufgebraucht waren. Sie wird automatisch versendet, sobald Sie aufladen – nichts geht verloren.
Nächste Schritte
- Ergänzen Sie
limitRate: { id: 'contact', throttle: 30_000 }in den Provider-Optionen, um pro Gerät nur eine Nachricht alle 30 Sekunden zuzulassen. - Schicken Sie dem Nutzer eine Bestätigung mit der Vorlage Automatische Antwort: Danke für Ihre Nachricht aus der Galerie.


