smartformify
Pricing

React and ReactJS

Connect a React Form Without a Custom API

Keep the current component and form fields. Send the values to SmartFormify, then use React state for loading, success, error, and redirect behavior.

Create EndpointView React Component

Component flow

FormData

Fetch

State

The request stays in the component. A separate Express or serverless form route is optional.

Component setup

Submit directly from the browser

SmartFormify returns the JSON used by the component for success, errors, redirects, and thank-you content. Use the environment tab when deployments need different endpoint URLs.

React contact form

jsx

This form uses FormData and React state to handle the JSON returned by SmartFormify. The same request shape works with a controlled form.

import { useState } from "react";

const ENDPOINT_URL = "https://api.smartformify.com/fe/YOUR_ENDPOINT_KEY";

export default function ContactForm() {
  const [status, setStatus] = useState("idle");
  const [message, setMessage] = useState("");

  async function handleSubmit(event) {
    event.preventDefault();
    const form = event.currentTarget;

    if (!form.reportValidity()) return;

    setStatus("loading");
    setMessage("");

    const data = Object.fromEntries(new FormData(form).entries());

    try {
      const response = await fetch(ENDPOINT_URL, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ data })
      });

      const result = await response.json();
      if (!response.ok || !result.success) {
        throw new Error(result.message || "Submission failed.");
      }

      if (result.data.redirect_url) {
        window.location.assign(result.data.redirect_url);
        return;
      }

      setMessage(result.data.thank_you_content);
      setStatus("success");
      form.reset();
    } catch (error) {
      setMessage(error.message);
      setStatus("error");
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Email
        <input type="email" name="email" required />
      </label>
      <label>
        Message
        <textarea name="message" required />
      </label>
      <button disabled={status === "loading"}>
        {status === "loading" ? "Sending..." : "Send"}
      </button>
      {message && (
        <div
          role={status === "error" ? "alert" : "status"}
          dangerouslySetInnerHTML={{ __html: message }}
        />
      )}
    </form>
  );
}

Keep the component state predictable

01

Idle

The form is ready and values can be edited.

02

Loading

Disable submit while the request is active.

03

Success

Show confirmation or follow the redirect.

04

Error

Keep values and display the returned message.

Uncontrolled form

Read fields with FormData

Use this approach when React does not need every field value during typing. It keeps the submit handler short.

Controlled form

Send the current state object

Use this approach when the component already stores values for conditional UI or custom validation. Send that object inside data.

Before deploying the React form

Add local, preview, and production domains only when they need browser access
Test loading, success, error, and redirect behavior
Do not put private application secrets in public environment variables