Ako vytvoriť kontaktný formulár v React Native (a Expo), ktorý posiela e-maily
Kontaktný formulár v React Native, ktorý vám každú správu pošle e-mailom – so stavom odosielania, ochranou pred robotmi a bez backendu. Funguje v Expo aj v čistom React Native.
Aktualizované:
Do aplikácie v React Native alebo Expo pridáte kontaktný formulár s balíčkom
@frontmail/react-native: provider, hook useSendEmail, ktorý sleduje stav odosielania, a hotový
komponent Turnstile proti robotom. E-mail odchádza cez vašu vlastnú schránku.
Potrebujete: bezplatný účet Frontmail, projekt v Expo alebo React Native a zhruba desať minút.
1. Pripojte schránku a vytvorte šablónu
- E-mailové služby → Pridať službu: pripojte Gmail, Outlook, SMTP alebo transakčného poskytovateľa, zaškrtnite Nastaviť ako predvolenú, Overiť a uložiť.
- Šablóny → Z galérie → Kontaktný formulár → Použiť šablónu. Povinné parametre:
name,email,message; nepovinné:phone,topic. - Z karty Kód skopírujte ID šablóny (
tpl_…).
2. Povoľte mobilné aplikácie
- Zabezpečenie → Mobilné aplikácie → Povoliť mobilné aplikácie → Uložiť. Aplikácie
neposielajú hlavičku
Origin, takže bez tohto prepínača API odpovedáorigin_not_allowed. - Šablóna → Nastavenia → Ochrana → Vyžadovať CAPTCHA (Turnstile). Aplikácia používa zdieľaný widget Turnstile od Frontmailu; kľúče od Cloudflare nepotrebujete.
3. Inštalácia
npx expo install @frontmail/react-native @react-native-async-storage/async-storage react-native-webview
V čistom projekte React Native použite npm i s rovnakými balíčkami a spustite npx pod-install.
4. Vytvorte formulár
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ýnimku: vráti výsledok alebo undefined a status prejde z idle na
sending a potom na sent, held alebo error. Opakované pokusy po sieťových chybách
používajú jeden idempotency kľúč, takže ani používateľ vo vlaku vám nepošle tú istú správu dvakrát.
5. Vyskúšajte to
Spustite aplikáciu (npx expo start), vyplňte formulár a ťuknite na Send. E-mail vám príde
do schránky a objaví sa v dashboarde v časti História.
origin_not_allowed– Povoliť mobilné aplikácie je vypnuté alebo neuložené.captcha_required– overenie Turnstile ešte neskončilo; tlačidlo zostane neaktívne, kým nemá token.invalid_template_params– povinné pole je prázdne alebo e-mail nie je platný.
heldznamená, že správa bola prijatá v čase, keď ste mali minuté kredity. Hneď po dobití sa automaticky odošle – nič sa nezahodí.
Ďalšie kroky
- Pridajte do možností providera
limitRate: { id: 'contact', throttle: 30_000 }a z jedného zariadenia pôjde odoslať najviac jedna správa za 30 sekúnd. - Pošlite používateľovi potvrdenie šablónou Automatická odpoveď: ďakujeme za správu z galérie.


