React Components

Overview

React components and hooks for building forms with Formr. Provides pre-built components and hooks that handle form submission, validation, and error handling.

Installation

npm install formr-ui
# or
pnpm add formr-ui
# or
yarn add formr-ui

Requires React 18+

Quick Start

import { useFormr, Form, Field, Errors } from 'formr-ui';

export default function ContactForm() {
  const { submit, errors, pending } = useFormr({
    formId: 'contact',
    apiKey: process.env.NEXT_PUBLIC_FORMR_KEY,
  });

  return (
    <Form onSubmit={submit}>
      <Field 
        name="email" 
        type="email" 
        label="Email" 
        required 
      />
      {errors.email && <Errors field="email" message={errors.email} />}
      
      <Field 
        name="message" 
        type="textarea" 
        label="Message" 
        required 
      />
      
      <button disabled={pending}>
        {pending ? 'Submitting...' : 'Send'}
      </button>
      
      {errors._form && <Errors message={errors._form} />}
    </Form>
  );
}

Using Hooks Directly

import { useFormr } from 'formr-ui/hooks';

Components

<Form>

Wrapper component that handles form submission.

Props:

  • onSubmit - Submit handler function

  • All standard HTML form props supported

Example:

<Form onSubmit={submit}>
  {/* form fields */}
</Form>

<Field>

Input field component.

Props:

  • name - Field name (required)

  • label - Field label

  • type - Input type (text, email, number, textarea, etc.)

  • All standard HTML input props supported

Example:

<Field 
  name="email" 
  type="email" 
  label="Email Address" 
  required 
  placeholder="you@example.com"
/>

<Errors>

Error display component.

Props:

  • field - Field name to display errors for

  • message - Error message to display

  • errors - Error object from useFormr

Example:

{errors.email && <Errors field="email" message={errors.email} />}
{errors._form && <Errors message={errors._form} />}

Hook: useFormr(options)

React hook for form management.

Options

  • formId - Form ID (required)

  • apiKey - API key (optional)

  • baseUrl - Base URL (optional)

  • sessionId - Session ID (optional)

Returns

  • submit(data) - Submit function

  • errors - Error object

  • pending - Loading state

  • reset() - Reset errors and pending state

Example

const { submit, errors, pending, reset } = useFormr({
  formId: 'contact-form',
  apiKey: process.env.NEXT_PUBLIC_FORMR_KEY,
});

Plain HTML Enhancement

Add the browser script to any HTML form:

<form method="post" action="https://api.formr.dev/submit" data-formr="contact">
  <input name="email" type="email" required />
  <input name="message" type="text" required />
  <button>Send</button>
</form>

<script async src="https://cdn.formr.dev/v1/browser.min.js"></script>

The script will:

  • Intercept form submissions

  • Validate client-side (optional, UX only)

  • Submit via Formr API

  • Handle success/error states

Examples

Basic Form

import { useFormr, Form, Field, Errors } from 'formr-ui';

export default function ContactForm() {
  const { submit, errors, pending } = useFormr({
    formId: 'contact-form',
  });

  return (
    <Form onSubmit={submit}>
      <Field name="email" type="email" label="Email" required />
      {errors.email && <Errors field="email" />}
      
      <Field name="message" type="textarea" label="Message" required />
      
      <button disabled={pending}>
        {pending ? 'Submitting...' : 'Send'}
      </button>
    </Form>
  );
}

Custom Styled Form

import { useFormr, Form, Field, Errors } from 'formr-ui';

export default function StyledContactForm() {
  const { submit, errors, pending } = useFormr({
    formId: 'contact-form',
  });

  return (
    <Form onSubmit={submit} className="max-w-md mx-auto">
      <div className="mb-4">
        <Field 
          name="email" 
          type="email" 
          label="Email" 
          required 
          className="w-full p-2 border rounded"
        />
        {errors.email && (
          <Errors field="email" className="text-red-500 text-sm mt-1" />
        )}
      </div>
      
      <div className="mb-4">
        <Field 
          name="message" 
          type="textarea" 
          label="Message" 
          required 
          className="w-full p-2 border rounded"
        />
      </div>
      
      <button 
        disabled={pending}
        className="bg-blue-500 text-white px-4 py-2 rounded disabled:opacity-50"
      >
        {pending ? 'Submitting...' : 'Send'}
      </button>
    </Form>
  );
}

Using Hook Without Components

import { useFormr } from 'formr-ui/hooks';

export default function CustomForm() {
  const { submit, errors, pending } = useFormr({
    formId: 'contact-form',
  });

  const handleSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData(e.target);
    const answers = Object.fromEntries(formData);
    await submit({ answers });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="email" type="email" required />
      {errors.email && <div className="error">{errors.email}</div>}
      <button disabled={pending}>Submit</button>
    </form>
  );
}

Features

  • Light Client-side Validation: Required/min/max/pattern/enum for instant UX

  • Server Validates Everything: Client checks are advisory, server is authoritative

  • Unstyled Primitives: Bring your own styles

  • TypeScript Support: Full TypeScript definitions

  • Tree-shakeable: Only import what you need

Next Steps

  • Development Tools - Other development tools

  • SDK Guide - JavaScript/TypeScript SDK

  • API Reference - Complete API documentation

Last updated