---
name: forminit-html
description: Integrates Forminit headless form backend into HTML and static websites using the CDN SDK (2 KB). Creates forms with typed blocks (sender, text, email, phone, file, rating, date, select, radio, checkbox, country, number) and handles submission via JavaScript. Use when building client-side HTML forms that need a backend, collecting form submissions on static sites, or adding contact, feedback, or file upload forms to any HTML page. Do not use for Next.js (use forminit-nextjs) or Nuxt.js (use forminit-nuxtjs).
metadata:
  author: forminit
  version: "1.0"
---

# Forminit — HTML/Static Site Integration

> Forminit is a headless form backend API. You build the form UI, Forminit handles submission, validation, storage, and notifications. This skill is for client-side HTML forms using the CDN SDK.

## Constraints

- Client-side only — never use or ask for API keys. User must set form to "Public" mode.
- All field names use prefix pattern: `fi-{type}-{name}`
- Sender block: max 1 per form. Use for submitter's contact info.
- Default to `fi-sender-firstName` + `fi-sender-lastName`. Use `fi-sender-fullName` only if user wants a single name field.
- For non-submitter emails/phones/countries, use field blocks: `fi-email-invitee`, `fi-phone-emergency`, `fi-country-shipping`
- File uploads require FormData (not JSON)
- Max 50 blocks per form, max 25 MB total files
- Show success message on page after submit (no redirect unless requested)

## SDK Setup

```html
<script src="https://forminit.com/sdk/v1/forminit.js"></script>
```

SDK auto-captures: UTM params, ad click IDs (gclid, fbclid, msclkid, ttclid, twclid), referrer, geolocation.

## Complete Example

```html
<form id="my-form">
  <input type="text" name="fi-sender-firstName" placeholder="First name" required />
  <input type="text" name="fi-sender-lastName" placeholder="Last name" required />
  <input type="email" name="fi-sender-email" placeholder="Email" required />
  <textarea name="fi-text-message" placeholder="Message" required></textarea>
  <button type="submit">Send</button>
</form>
<p id="form-status"></p>

<script src="https://forminit.com/sdk/v1/forminit.js"></script>
<script>
  const forminit = new Forminit();
  document.getElementById('my-form').addEventListener('submit', async (e) => {
    e.preventDefault();
    const { data, redirectUrl, error } = await forminit.submit('FORM_ID', new FormData(e.target));
    if (error) {
      document.getElementById('form-status').textContent = error.message;
      return;
    }
    document.getElementById('form-status').textContent = 'Sent successfully!';
    e.target.reset();
  });
</script>
```

Replace `FORM_ID` with the form ID from https://app.forminit.com.

## Form Blocks Reference

### Sender Block — `fi-sender-{property}`

One per form. Collects submitter info. At least one property required.

```
fi-sender-email        → <input type="email" name="fi-sender-email" />
fi-sender-firstName    → <input type="text" name="fi-sender-firstName" />
fi-sender-lastName     → <input type="text" name="fi-sender-lastName" />
fi-sender-fullName     → <input type="text" name="fi-sender-fullName" />
fi-sender-phone        → <input type="tel" name="fi-sender-phone" />
fi-sender-company      → <input type="text" name="fi-sender-company" />
fi-sender-position     → <input type="text" name="fi-sender-position" />
fi-sender-title        → <input type="text" name="fi-sender-title" />
fi-sender-userId       → <input type="text" name="fi-sender-userId" />
fi-sender-address      → <input type="text" name="fi-sender-address" />
fi-sender-city         → <input type="text" name="fi-sender-city" />
fi-sender-country      → <input type="text" name="fi-sender-country" />
```

### Field Blocks — `fi-{type}-{name}`

Each name must be unique. Up to 50 total blocks.

```
text      fi-text-{name}       → <input type="text" name="fi-text-message" />
number    fi-number-{name}     → <input type="number" name="fi-number-quantity" />
email     fi-email-{name}      → <input type="email" name="fi-email-invitee" />
phone     fi-phone-{name}      → <input type="tel" name="fi-phone-emergency" />          Validation: E.164 (+12025550123)
url       fi-url-{name}        → <input type="url" name="fi-url-website" />
date      fi-date-{name}       → <input type="date" name="fi-date-appointment" />        Validation: ISO 8601 (YYYY-MM-DD)
rating    fi-rating-{name}     → <input type="number" name="fi-rating-satisfaction" />   Validation: integer 1–5
select    fi-select-{name}     → <select name="fi-select-plan">...</select>              Supports multi-select (string[])
radio     fi-radio-{name}      → <input type="radio" name="fi-radio-priority" />         Single choice (string)
checkbox  fi-checkbox-{name}   → <input type="checkbox" name="fi-checkbox-features" />   Supports multi-choice (string[])
file      fi-file-{name}       → <input type="file" name="fi-file-resume" />             Add [] for multiple: fi-file-photos[]
country   fi-country-{name}    → <select name="fi-country-shipping">...</select>         Validation: ISO 3166-1 alpha-2
```

### Tracking Block — `fi-tracking-{property}` (auto-captured by SDK)

One per form. Usually not needed — SDK captures these automatically.

```
fi-tracking-utmSource, fi-tracking-utmMedium, fi-tracking-utmCampaign, fi-tracking-utmTerm, fi-tracking-utmContent
```

## JSON Submission (alternative to FormData)

Use when building payloads programmatically. Cannot be used with file uploads.

```js
await forminit.submit('FORM_ID', {
  blocks: [
    { type: 'sender', properties: { email: '...', firstName: '...', lastName: '...' } },
    { type: 'text', name: 'message', value: '...' },
    { type: 'rating', name: 'satisfaction', value: 4 },
    { type: 'select', name: 'plan', value: 'pro' }
  ]
});
```

Sender uses `{ type, properties }`. All other blocks use `{ type, name, value }`.

## SDK Response

```js
const { data, redirectUrl, error } = await forminit.submit(formId, payload);
```

Success: `data.hashId` (submission ID), `data.date`, `data.blocks` (submitted values), `redirectUrl` (thank-you page URL).

Error: `error.error` (code like `FI_SCHEMA_FORMAT_EMAIL`), `error.code` (HTTP status), `error.message` (human-readable).

## Common Mistakes

- Using `name="email"` instead of `name="fi-sender-email"` — all fields must use the `fi-` prefix or the submission will be empty.
- Using `name="fi-sender-name"` — there is no `name` property on sender. Use `fi-sender-firstName` + `fi-sender-lastName` or `fi-sender-fullName`.
- Sending phone without E.164 format — `5551234567` will be rejected, must be `+15551234567`.
- Using JSON with file uploads — files only work with FormData.
- Adding an API key to client-side code — HTML integration uses Public mode, no API key needed or allowed.
- Using `fi-file-resume` for multiple files — append `[]` to the name: `fi-file-photos[]`.
- Forgetting `event.preventDefault()` — without it the browser submits the form as a page navigation instead of using the SDK.

## Spam Protection (only if user requests)

- reCAPTCHA: https://forminit.com/docs/recaptcha/
- hCaptcha: https://forminit.com/docs/hcaptcha/
