React
Client-side React component posting form-encoded data. Drop into any React app — no React-specific SDK required.
One-liner
// Assumes you already created the endpoint with: // curl -X POST https://gopigeon.dev/new -d 'recipient=you@example.com' // → { "endpoint_url": "https://gopigeon.dev/f/f_abc123def456xyz0", ... } import { useState } from 'react'; const ENDPOINT = 'https://gopigeon.dev/f/f_abc123def456xyz0'; export function ContactForm() { const [status, setStatus] = useState('idle'); async function onSubmit(e) { e.preventDefault(); setStatus('sending'); const body = new URLSearchParams(new FormData(e.currentTarget)).toString(); const r = await fetch(ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body, }); setStatus(r.ok ? 'sent' : 'error'); } return ( <form onSubmit={onSubmit}> <input name="name" required /> <input name="email" type="email" required /> <textarea name="message" required /> <button type="submit" disabled={status === 'sending'}>Send</button> {status === 'sent' && <p>Thanks!</p>} </form> ); }
How it works
Build a FormData from the submitted <form> element, convert to URLSearchParams to get a form-encoded body, then fetch the endpoint with Content-Type: application/x-www-form-urlencoded. The status state flips through idle → sending → sent (or error) so the UI can react.
The ENDPOINT constant holds the URL the one-time curl call returned — paste it verbatim; do not rewrite the form ID. gopigeon does not care whether the request is same-origin or cross-origin, so this works from a static site, a Next.js client page, or a Vite dev server identically.
The email you passed as recipient above gets a one-click claim link on the first real submission — that is how you become the authenticated owner.