Integração de formulário de contato React (aplicativos Vite e de página única)
Como adicionar formulários de contato e feedback a aplicativos React de página única (SPA) desenvolvidos com Vite ou Create React App, apresentando defesa contra spam honeypot e notificações instantâneas na caixa de entrada.
1. Componente padrão do formulário de contato React com Vite
Este componente React leve usa ganchos React padrão (useState) e a API Fetch do navegador para enviar diretamente ao seu endpoint público Lugatu. Não são necessárias bibliotecas de formulários externas ou servidores back-end.
import React, { useState } from 'react';
export function ContactForm() {
const [formData, setFormData] = useState({ name: '', email: '', message: '', _gotcha: '' });
const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
const [errorMessage, setErrorMessage] = useState('');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (formData._gotcha) return; // Silent discard for automated bot traps
setStatus('submitting');
setErrorMessage('');
try {
const response = await fetch('https://www.lugatu.com/api/v1/public/forms/YOUR_PUBLIC_FORM_ID/submissions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
fields: {
name: formData.name,
email: formData.email,
message: formData.message,
},
honeypot: formData._gotcha,
}),
});
if (!response.ok) {
throw new Error('Failed to deliver message');
}
setStatus('success');
setFormData({ name: '', email: '', message: '', _gotcha: '' });
} catch (err: any) {
setStatus('error');
setErrorMessage(err.message || 'Submission error. Please try again.');
}
};
return (
<form onSubmit={handleSubmit} className="space-y-4 max-w-md">
<div>
<label htmlFor="react-name" className="block text-sm font-semibold mb-1">Your Name</label>
<input
id="react-name"
type="text"
required
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
className="w-full border rounded-xl p-2.5"
/>
</div>
<div>
<label htmlFor="react-email" className="block text-sm font-semibold mb-1">Email Address</label>
<input
id="react-email"
type="email"
required
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
className="w-full border rounded-xl p-2.5"
/>
</div>
<div>
<label htmlFor="react-message" className="block text-sm font-semibold mb-1">Message</label>
<textarea
id="react-message"
rows={4}
required
value={formData.message}
onChange={(e) => setFormData({ ...formData, message: e.target.value })}
className="w-full border rounded-xl p-2.5"
/>
</div>
<!-- Honeypot spam defense -->
<input
type="text"
name="_gotcha"
value={formData._gotcha}
onChange={(e) => setFormData({ ...formData, _gotcha: e.target.value })}
style={{ display: 'none' }}
tabIndex={-1}
autoComplete="off"
/>
<button
type="submit"
disabled={status === 'submitting'}
className="btn-primary-editorial py-2.5 px-6"
>
{status === 'submitting' ? 'Sending...' : 'Send Message'}
</button>
{status === 'success' && (
<p className="text-sm text-green-700 font-medium">Thank you! Your message was delivered.</p>
)}
{status === 'error' && (
<p className="text-sm text-red-600">{errorMessage}</p>
)}
</form>
);
}
2. Integração com React Hook Form e Formik
O modelo de envio JSON padrão Lugatu integra-se facilmente com bibliotecas de validação de formulários como React Hook Form, Formik ou Zod. Passe os valores serializados diretamente para o objeto de carga útil dos campos.
// React Hook Form submission handler
const onSubmit = async (data: FormValues) => {
const res = await fetch(`https://www.lugatu.com/api/v1/public/forms/${import.meta.env.VITE_LUGATU_FORM_ID}/submissions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fields: data }),
});
return res.ok;
};
3. Variáveis de ambiente e separação secreta no React
No Vite, as variáveis públicas são prefixadas com VITE_. Use VITE_LUGATU_FORM_ID para o ID do formulário público. Nunca exponha sua chave de API de servidor para servidor (lug_live_...) dentro do código-fonte ou repositórios do lado do cliente.
As chaves de API Live começando com lug_live_ são estritamente reservadas para execução de servidor para servidor. Qualquer solicitação do navegador enviada com uma chave de API ativa é rejeitada com HTTP 403.
Invariante de segurança e autenticação
Invariante de segurança: nunca prefixe chaves de API ativas com VITE_ ou REACT_APP_. Os clientes do navegador devem enviar exclusivamente para endpoints públicos sem chaves de API.
Solução de problemas e erros comuns de ingestão
Certifique-se de enviar para o endpoint público (https://www.lugatu.com/api/v1/public/forms/YOUR_PUBLIC_FORM_ID/submissions). Os endpoints de servidor para servidor (POST /api/v1/forms/{id}/submissions) bloqueiam explicitamente as origens do navegador.
Perguntas frequentes
Posso usar React Hook Form ou Formik com Lugatu?
Sim. Lugatu aceita JSON padrão com um objeto de campos. Qualquer biblioteca de formulários React pode serializar seus valores e enviá-los ao endpoint público.
Pronto para criar o endpoint do seu formulário?
Comece gratuitamente em segundos. Não é necessário cartão de crédito.