Jak zrobić formularz kontaktowy w React Native (i Expo), który wysyła e-maile
Formularz kontaktowy w React Native, który wysyła Ci każdą wiadomość e-mailem – ze stanem wysyłania, ochroną przed botami i bez backendu. Działa w Expo i w czystym React Native.
Zaktualizowano:
Dodasz formularz kontaktowy do aplikacji w React Native albo Expo z pakietem
@frontmail/react-native: provider, hook useSendEmail, który śledzi stan wysyłania, i gotowy
komponent Turnstile przeciw botom. E-mail wychodzi przez Twoją własną skrzynkę.
Potrzebujesz: darmowego konta Frontmail, projektu w Expo lub React Native i około dziesięciu minut.
1. Podłącz skrzynkę i utwórz szablon
- Usługi e-mail → Dodaj usługę: podłącz Gmail, Outlook, SMTP albo dostawcę e-maili transakcyjnych, zaznacz Ustaw jako domyślną, Zweryfikuj i zapisz.
- Szablony → Z galerii → Formularz kontaktowy → Użyj szablonu. Parametry wymagane:
name,email,message; opcjonalne:phone,topic. - Skopiuj ID szablonu (
tpl_…) z zakładki Kod.
2. Zezwól na aplikacje mobilne
- Bezpieczeństwo → Aplikacje mobilne → Zezwól na aplikacje mobilne → Zapisz.
Aplikacje nie wysyłają nagłówka
Origin, więc bez tego przełącznika API odpowiadaorigin_not_allowed. - Szablon → Ustawienia → Ochrona → Wymagaj CAPTCHA (Turnstile). Aplikacja korzysta ze wspólnego widżetu Turnstile Frontmail; klucze Cloudflare nie są potrzebne.
3. Instalacja
npx expo install @frontmail/react-native @react-native-async-storage/async-storage react-native-webview
W czystym projekcie React Native użyj npm i z tymi samymi pakietami i uruchom npx pod-install.
4. Zbuduj formularz
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 nigdy nie rzuca wyjątku: zwraca wynik albo undefined, a status przechodzi z idle do
sending, a potem do sent, held lub error. Ponowienia po błędach sieci używają jednego klucza
idempotencji, więc użytkownik w pociągu nigdy nie wyśle Ci tej samej wiadomości dwa razy.
5. Przetestuj
Uruchom aplikację (npx expo start), wypełnij formularz i stuknij Send. E-mail trafi do Twojej
skrzynki i do sekcji Historia w panelu.
origin_not_allowed– opcja Zezwól na aplikacje mobilne jest wyłączona albo niezapisana.captcha_required– weryfikacja Turnstile jeszcze się nie zakończyła; przycisk pozostaje nieaktywny, dopóki nie ma tokenu.invalid_template_params– wymagane pole jest puste albo e-mail jest nieprawidłowy.
heldoznacza, że wiadomość została przyjęta, gdy kredyty były wyczerpane. Wyjdzie automatycznie, gdy tylko doładujesz konto – nic nie przepada.
Co dalej
- Dodaj
limitRate: { id: 'contact', throttle: 30_000 }do opcji providera, żeby pozwolić na jedną wiadomość na 30 sekund z jednego urządzenia. - Wyślij użytkownikowi potwierdzenie szablonem Automatyczna odpowiedź: dziękujemy za wiadomość z galerii.


