Jak v React Native (a Expo) udělat kontaktní formulář, který odesílá e-maily
Kontaktní formulář v React Native, který vám každou zprávu pošle e-mailem – se stavem odesílání, ochranou proti botům a bez backendu. Funguje v Expo i v čistém React Native.
Aktualizováno:
Do aplikace v React Native nebo Expo přidáte kontaktní formulář s balíčkem @frontmail/react-native:
provider, hook useSendEmail, který sleduje stav odesílání, a hotovou komponentu Turnstile proti
botům. E-mail odchází přes vaši vlastní schránku.
Budete potřebovat: bezplatný účet Frontmail, projekt v Expo nebo React Native a zhruba deset minut.
1. Připojte schránku a vytvořte šablonu
- E-mailové služby → Přidat službu: připojte Gmail, Outlook, SMTP nebo transakční službu, zaškrtněte Nastavit jako výchozí a klikněte na Ověřit a uložit.
- Šablony → Z galerie → Kontaktní formulář → Použít šablonu. Povinné parametry:
name,email,message; nepovinné:phone,topic. - Na záložce Kód pro web zkopírujte ID šablony (
tpl_…).
2. Povolte mobilní aplikace
- Zabezpečení → Mobilní aplikace → Povolit mobilní aplikace → Uložit. Aplikace
neposílají hlavičku
Origin, takže bez tohoto přepínače API odpovídáorigin_not_allowed. - Šablona → Nastavení → Ochrana → Vyžadovat CAPTCHA (Turnstile). Aplikace používá sdílený widget Turnstile od Frontmailu; klíče od Cloudflaru nepotřebujete.
3. Instalace
npx expo install @frontmail/react-native @react-native-async-storage/async-storage react-native-webview
V čistém projektu React Native nainstalujte stejné balíčky přes npm i a spusťte npx pod-install.
4. Postavte formulář
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 nikdy nevyhodí výjimku: vrátí výsledek nebo undefined a status přechází z idle
na sending a pak na sent, held nebo error. Opakované pokusy po chybách sítě používají
jeden idempotency key, takže ani uživatel ve vlaku vám tutéž zprávu nepošle dvakrát.
5. Vyzkoušejte to
Spusťte aplikaci (npx expo start), vyplňte formulář a klepněte na Send. E-mail dorazí do
vaší schránky a do sekce Historie v dashboardu.
origin_not_allowed– volba Povolit mobilní aplikace je vypnutá nebo neuložená.captcha_required– kontrola Turnstile ještě neskončila; tlačítko zůstane neaktivní, dokud nemá token.invalid_template_params– povinné pole je prázdné nebo e-mail není platný.
heldznamená, že zpráva byla přijata ve chvíli, kdy jste měli vyčerpané kredity. Odejde automaticky, jakmile je doplníte – nic se nezahodí.
Další kroky
- Přidejte do options provideru
limitRate: { id: 'contact', throttle: 30_000 }a povolíte tak jednu zprávu za 30 sekund z jednoho zařízení. - Pošlete uživateli potvrzení šablonou Automatická odpověď: díky za zprávu z galerie.


