# React Integration Guide

Complete guide to integrate MyFormConnect with React

      Setup time: **5-10 minutes
      Difficulty: **Easy
        Compatible versions: **React 17+ (Vite, CRA, Next.js, etc.)**

Add working forms to any React app in under 10 minutes — no backend, server routes, or email services. Create a form in your MyFormConnect dashboard, copy the Form Action URL, and POST `FormData` with `fetch`.

## ** Prerequisites

- ** A MyFormConnect account — [sign up here (free)](/users/sign_up)
- ** A form created in your [MyFormConnect dashboard](/account/)
- ** Your unique Form Action URL (e.g. `https://myformconnect.io/f/YOUR_FORM_UUID`)
- ** Any existing React project (Vite, Next.js, Create React App, etc.)

## ** Integration Methods

### Contact form

                5 minutes

                Easy

A full contact form with inline success/error states. Submissions go to MyFormConnect with spam and honeypot protection handled for you.

                  1

#### Create your form and copy the Form Action URL

                    Log in to your [MyFormConnect dashboard](/account/). Add a domain (use `http://localhost:5173` or `http://localhost:3000` for local work), create a form, then copy the Form Action URL.

1. Open **Domains** → add or select a domain
2. Set Domain URL to your React origin (local or production)
3. Add a new form and copy `https://myformconnect.io/f/YOUR_FORM_UUID`

##### Important Note

                            Adding localhost as a Domain URL avoids domain-restriction / CORS issues while developing.

                  2

#### Create a React form component

                    Add `src/components/ContactForm.jsx` (or similar). Replace `YOUR_FORM_UUID` with your real UUID.

```
import React, { useState } from 'react';

// Paste your MyFormConnect Form Action URL here:
const CONTACT_FORM_ACTION_URL = 'https://myformconnect.io/f/YOUR_FORM_UUID';

export default function ContactForm() {
  const [status, setStatus] = useState('idle'); // 'idle' | 'submitting' | 'success' | 'error'
  const [errorMessage, setErrorMessage] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    const form = e.currentTarget;
    setStatus('submitting');
    setErrorMessage('');

    try {
      const response = await fetch(CONTACT_FORM_ACTION_URL, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'X-Requested-With': 'XMLHttpRequest',
        },
        body: new FormData(form),
      });

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

      setStatus('success');
      form.reset();
    } catch (err) {
      setStatus('error');
      setErrorMessage('Unable to submit your message. Please try again.');
    }
  };

  const inputStyle = {
    width: '100%',
    boxSizing: 'border-box',
    padding: '10px 12px',
    borderRadius: '6px',
    border: '1px solid #cbd5e1',
    fontSize: '14px',
    fontFamily: 'inherit',
  };

  if (status === 'success') {
    return (
      <div style={{ textAlign: 'center', padding: '24px', background: '#f0fdf4', borderRadius: '8px', color: '#166534' }}>
        <h3 style={{ margin: '0 0 8px 0' }}>Thank You!</h3>
        <p style={{ margin: 0 }}>Your message has been sent successfully. We will get back to you soon.</p>
        <button
          type="button"
          onClick={() => setStatus('idle')}
          style={{ marginTop: '16px', padding: '8px 16px', cursor: 'pointer', borderRadius: '6px', border: '1px solid #bbf7d0', background: '#ffffff' }}
        >
          Send Another Message
        </button>
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '14px', maxWidth: '480px', width: '100%', boxSizing: 'border-box' }}>
      {status === 'error' && (
        <div style={{ color: '#b91c1c', background: '#fef2f2', padding: '10px 12px', borderRadius: '6px', fontSize: '13px' }}>
          {errorMessage}
        </div>
      )}

      <div>
        <label htmlFor="name" style={{ display: 'block', fontWeight: 600, fontSize: '13px', marginBottom: '6px' }}>
          Full Name *
        </label>
        <input id="name" name="name" type="text" placeholder="Jane Doe" required style={inputStyle} />
      </div>

      <div>
        <label htmlFor="email" style={{ display: 'block', fontWeight: 600, fontSize: '13px', marginBottom: '6px' }}>
          Email Address *
        </label>
        <input id="email" name="email" type="email" placeholder="jane@example.com" required style={inputStyle} />
      </div>

      <div>
        <label htmlFor="message" style={{ display: 'block', fontWeight: 600, fontSize: '13px', marginBottom: '6px' }}>
          Message *
        </label>
        <textarea id="message" name="message" rows={4} placeholder="How can we help you?" required style={{ ...inputStyle, resize: 'vertical' }} />
      </div>

      <button
        type="submit"
        disabled={status === 'submitting'}
        style={{
          padding: '12px',
          background: '#2D5DEA',
          color: '#ffffff',
          fontWeight: 600,
          fontSize: '14px',
          border: 'none',
          borderRadius: '6px',
          cursor: status === 'submitting' ? 'not-allowed' : 'pointer',
          opacity: status === 'submitting' ? 0.7 : 1,
        }}
      >
        {status === 'submitting' ? 'Sending…' : 'Send Message'}
      </button>

      <p style={{ fontSize: '11px', color: '#64748b', textAlign: 'center', margin: '4px 0 0 0' }}>
        Powered by{' '}
        <a href="https://myformconnect.io" target="_blank" rel="noopener noreferrer" style={{ color: '#2D5DEA', fontWeight: 600, textDecoration: 'none' }}>
          MyFormConnect
        </a>
      </p>
    </form>
  );
}
```

##### Important Note

                            Always give each input a `name`. Do not set `Content-Type`. Do not `JSON.stringify` — pass `new FormData(form)` as the body.

                  3

#### Run and verify

                    Import the component into a page, start your app, submit a test entry, then check **Responses / Leads** in MyFormConnect.

1. Import `ContactForm` into `App.jsx` or a contact page
2. Run `npm run dev` (or your usual start command)
3. Submit the form and confirm the lead in the dashboard

```
import ContactForm from './components/ContactForm';

export default function App() {
  return (
    <div style={{ padding: '40px' }}>
      <h1>Contact Us</h1>
      <ContactForm />
    </div>
  );
}
```

### Career / file upload

                5 minutes

                Easy

MyFormConnect accepts file uploads (PDF, DOC, and common office formats up to ~100 MB). Use `<input type="file" />` — `FormData` handles the rest.

                  1

#### Use a form UUID that allows file fields

                    Create or open a form in MyFormConnect that includes a resume/file field mapping, then copy its Form Action URL.

1. Create a careers (or similar) form in the dashboard
2. Copy `https://myformconnect.io/f/YOUR_FORM_UUID`

                  2

#### Add the career form component

                    Paste this component and replace the UUID. Do not set `Content-Type` when uploading files.

```
import React, { useState } from 'react';

const CAREERS_FORM_ACTION_URL = 'https://myformconnect.io/f/YOUR_FORM_UUID';

export default function CareerForm() {
  const [status, setStatus] = useState('idle');

  const handleSubmit = async (e) => {
    e.preventDefault();
    setStatus('submitting');

    try {
      const res = await fetch(CAREERS_FORM_ACTION_URL, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'X-Requested-With': 'XMLHttpRequest',
        },
        body: new FormData(e.currentTarget),
      });

      if (!res.ok) throw new Error('Submission error');
      setStatus('success');
    } catch {
      setStatus('error');
    }
  };

  if (status === 'success') {
    return <p>Application submitted! Our hiring team will review your profile.</p>;
  }

  const inputStyle = {
    width: '100%',
    boxSizing: 'border-box',
    padding: '9px 12px',
    borderRadius: '6px',
    border: '1px solid #cbd5e1',
    fontSize: '13px',
    fontFamily: 'inherit',
    marginBottom: '12px',
  };

  return (
    <form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', maxWidth: '480px', width: '100%', boxSizing: 'border-box' }}>
      <label htmlFor="position" style={{ fontWeight: 600, fontSize: '13px', marginBottom: '4px' }}>
        Position Applied For *
      </label>
      <select id="position" name="position" required style={inputStyle}>
        <option value="Frontend Developer">Frontend Developer</option>
        <option value="Full Stack Engineer">Full Stack Engineer</option>
        <option value="UI/UX Designer">UI/UX Designer</option>
        <option value="General Application">General Application</option>
      </select>

      <label htmlFor="name" style={{ fontWeight: 600, fontSize: '13px', marginBottom: '4px' }}>
        Full Name *
      </label>
      <input id="name" name="name" type="text" required style={inputStyle} />

      <label htmlFor="email" style={{ fontWeight: 600, fontSize: '13px', marginBottom: '4px' }}>
        Email Address *
      </label>
      <input id="email" name="email" type="email" required style={inputStyle} />

      <label htmlFor="portfolio" style={{ fontWeight: 600, fontSize: '13px', marginBottom: '4px' }}>
        Portfolio / GitHub / LinkedIn
      </label>
      <input id="portfolio" name="portfolio" type="url" placeholder="https://..." style={inputStyle} />

      <label htmlFor="resume" style={{ fontWeight: 600, fontSize: '13px', marginBottom: '4px' }}>
        Resume / CV (PDF or DOCX) *
      </label>
      <input id="resume" name="resume" type="file" accept=".pdf,.doc,.docx" required style={inputStyle} />

      <button
        type="submit"
        disabled={status === 'submitting'}
        style={{
          padding: '12px',
          background: '#2D5DEA',
          color: '#ffffff',
          fontWeight: 600,
          border: 'none',
          borderRadius: '6px',
          cursor: status === 'submitting' ? 'not-allowed' : 'pointer',
          fontSize: '14px',
        }}
      >
        {status === 'submitting' ? 'Uploading…' : 'Submit Application'}
      </button>

      <p style={{ fontSize: '11px', color: '#64748b', textAlign: 'center', marginTop: '8px' }}>
        Powered by{' '}
        <a href="https://myformconnect.io" target="_blank" rel="noopener noreferrer" style={{ color: '#2D5DEA', fontWeight: 600, textDecoration: 'none' }}>
          MyFormConnect
        </a>
      </p>
    </form>
  );
}
```

##### Important Note

                            Same golden rules as the contact form: `name` on every field, raw `FormData`, AJAX headers for JSON responses.

### Newsletter signup

                3 minutes

                Easy

A compact email capture for footers and landing pages.

                  1

#### Add a newsletter component

                    Replace `YOUR_FORM_UUID` with a form dedicated to email signups.

```
import React, { useState } from 'react';

const NEWSLETTER_FORM_ACTION_URL = 'https://myformconnect.io/f/YOUR_FORM_UUID';

export default function NewsletterForm() {
  const [status, setStatus] = useState('idle');

  const handleSubmit = async (e) => {
    e.preventDefault();
    setStatus('loading');
    try {
      const res = await fetch(NEWSLETTER_FORM_ACTION_URL, {
        method: 'POST',
        headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
        body: new FormData(e.currentTarget),
      });
      if (!res.ok) throw new Error();
      setStatus('success');
    } catch {
      setStatus('error');
    }
  };

  if (status === 'success') {
    return <p style={{ color: '#16a34a', fontSize: '13px' }}>✓ Subscribed successfully!</p>;
  }

  return (
    <form onSubmit={handleSubmit} style={{ display: 'flex', gap: '8px', maxWidth: '400px', width: '100%', boxSizing: 'border-box' }}>
      <input
        type="email"
        name="email"
        placeholder="Enter your email"
        required
        style={{
          flex: 1,
          boxSizing: 'border-box',
          padding: '9px 12px',
          borderRadius: '6px',
          border: '1px solid #cbd5e1',
          fontSize: '13px',
        }}
      />
      <button
        type="submit"
        disabled={status === 'loading'}
        style={{
          padding: '9px 16px',
          background: '#2D5DEA',
          color: '#ffffff',
          fontWeight: 600,
          border: 'none',
          borderRadius: '6px',
          cursor: status === 'loading' ? 'not-allowed' : 'pointer',
          fontSize: '13px',
          whiteSpace: 'nowrap',
        }}
      >
        {status === 'loading' ? 'Joining…' : 'Subscribe'}
      </button>
    </form>
  );
}
```

##### Important Note

                            The email input must include `name="email"` or the dashboard will show an empty submission.

## ** Troubleshooting

              Domain Restriction is blocking the request. Add `http://localhost:5173` / `http://localhost:3000` (or your production origin) under Domains / Allowed Domains, or temporarily turn Restrict Domain off while developing.

              The Form Action URL is wrong. Use `https://myformconnect.io/f/YOUR_FORM_UUID` with the real UUID from the dashboard — no spaces or leftover placeholders.

              Do not `JSON.stringify` the body. Pass `new FormData(e.currentTarget)` directly so MyFormConnect receives multipart form data.

              Add `Accept: 'application/json'` and `'X-Requested-With': 'XMLHttpRequest'` so MyFormConnect returns JSON `200` instead of a redirect SPA `fetch` cannot follow.

              Every input needs a `name` attribute. `id` or `placeholder` alone is not sent by `FormData`.

              Call `e.preventDefault()` as the first line of `handleSubmit`.

              In the dashboard, edit the form → enable **Notify on Email** → Update Form. Alerts go to your registered address. For help: [Support](/support) or [support@myformconnect.io](mailto:support@myformconnect.io).

#### Still having issues?

Can't find the answer you're looking for? Our support team is here to help with your integration.

          [** Contact Support](/support)

## ** Related Integrations

      [Getting Started Integration Guide →](/docs/getting-started)      [Custom Webhooks Integration Guide →](/docs/tools/code/custom-webhooks)      [WordPress Integration Guide →](/docs/platforms/cms/wordpress)

## ** References & Official Documentation

- ** [Getting Started Guide](/docs/getting-started)
- ** [Custom Webhooks](/docs/tools/code/custom-webhooks)

## ** Next Steps

#### ** Configure MyFormConnect

- ** Set up your timezone
- ** Configure lead notifications
- ** Set up advanced spam detection
- ** Add team members to your account

#### ** Advanced Features

- ** Use our custom form templates
- ** Try AI Insights for Leads
- ** Integrate with your CRM
- ** Set up automated workflows
