> ## Documentation Index
> Fetch the complete documentation index at: https://formbnb.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# React

> Use FormBnB with React applications

React forms can submit directly to FormBnB with `fetch` and `FormData`. No React-specific package is required.

## Contact Form

```tsx theme={null}
import { useState } from 'react';

const FORMBNB_ENDPOINT = 'https://api.formbnb.com/f/YOUR_ORG/YOUR_FORM';

export function ContactForm() {
  const [status, setStatus] = useState<'idle' | 'sending' | 'success' | 'error'>('idle');

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();

    if (status === 'sending') return;
    setStatus('sending');

    const form = event.currentTarget;
    const formData = new FormData(form);

    try {
      const response = await fetch(FORMBNB_ENDPOINT, {
        method: 'POST',
        body: formData,
        headers: { Accept: 'application/json' },
      });

      if (!response.ok) throw new Error('Submission failed');

      form.reset();
      setStatus('success');
    } catch {
      setStatus('error');
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="name" placeholder="Name" required />
      <input type="email" name="email" placeholder="Email" required />
      <textarea name="message" placeholder="Message" required />

      <button type="submit" disabled={status === 'sending'}>
        {status === 'sending' ? 'Sending...' : 'Send'}
      </button>

      {status === 'success' && <p>Thanks. Your message was sent.</p>}
      {status === 'error' && <p>Something went wrong. Please try again.</p>}
    </form>
  );
}
```

## With React Hook Form

```tsx theme={null}
import { useForm } from 'react-hook-form';

type ContactFields = {
  name: string;
  email: string;
  message: string;
};

export function ContactForm() {
  const { register, handleSubmit, reset, formState } = useForm<ContactFields>();

  async function onSubmit(data: ContactFields) {
    const response = await fetch('https://api.formbnb.com/f/YOUR_ORG/YOUR_FORM', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json',
      },
      body: JSON.stringify(data),
    });

    if (!response.ok) throw new Error('Submission failed');
    reset();
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name', { required: true })} placeholder="Name" />
      <input {...register('email', { required: true })} type="email" placeholder="Email" />
      <textarea {...register('message', { required: true })} placeholder="Message" />
      <button type="submit" disabled={formState.isSubmitting}>
        {formState.isSubmitting ? 'Sending...' : 'Send'}
      </button>
    </form>
  );
}
```

## File Uploads

```tsx theme={null}
export function ApplicationForm() {
  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();

    const response = await fetch('https://api.formbnb.com/f/YOUR_ORG/apply', {
      method: 'POST',
      body: new FormData(event.currentTarget),
      headers: { Accept: 'application/json' },
    });

    if (!response.ok) throw new Error('Submission failed');
  }

  return (
    <form onSubmit={handleSubmit} encType="multipart/form-data">
      <input name="email" type="email" required />
      <input name="resume" type="file" />
      <button type="submit">Apply</button>
    </form>
  );
}
```
