Menu

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://api.gopigeon.dev/new -d '[email protected]'
// → { "endpoint_url": "https://api.gopigeon.dev/f/f_abc123def456xyz0", ... }

import { useState } from 'react';

const ENDPOINT = 'https://api.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. See the claim flow for the full sequence.

Configure a thank-you redirect

Because you’re using fetch() here (not a native form POST), the browser doesn’t follow a 303 automatically — the response JSON is what your handler sees. If you want a server-side redirect anyway, set redirect_url in the dashboard after claiming; the API will still return 303 in headers and you can choose to honor it in your handler. For most React flows you’ll just navigate client-side after setStatus('sent') — no redirect_url needed.

CORS / allowed origins

By default Gopigeon allows cross-origin fetch() from any origin (allowed_origins: "*"), so this code works from a Vite dev server, a Next.js client page, or a static export. After you claim the endpoint, lock it down to your domain — set allowed_origins to a comma-separated list (e.g. https://yoursite.com,https://staging.yoursite.com) on the endpoint detail page in the dashboard.

Not what you're looking for? See the full surface at /llms.txt.