---
title: "Add a form to React"
description: "Mount a published or code-defined Fillo form in React with native controls and optional default CSS."
order: 12
type: "guide"
topic: "Frameworks"
tags:
  - "React"
  - "Vite"
  - "embed"
  - "SDK"
updated: "2026-07-15"
---

The React embed renders your Fillo form as native elements in your component tree — no iframe.

## Install and render

```bash
npm install @usefillo/react
```

```tsx
import { FilloForm } from "@usefillo/react";
import "@usefillo/react/styles.css";

export function FeedbackCard() {
  return (
    <section aria-labelledby="feedback-title">
      <h2 id="feedback-title">Product feedback</h2>
      <FilloForm
        formId="your-published-form-id"
        showTitle={false}
        onSubmitted={(responseId) => track("feedback_sent", { responseId })}
      />
    </section>
  );
}
```

Hiding the renderer title is only safe when the surrounding page supplies an equivalent visible heading.

## Use a code-defined schema when you need one

For a response-saving `defineForm` object, create a workspace client and pass both required props:

```tsx
import { FilloForm, createClient } from "@usefillo/react";

const client = createClient({ key: import.meta.env.VITE_FILLO_KEY });

<FilloForm form={yourForm} client={client} />
```

The client resolves or stages the code-defined form and gives submissions a workspace target. Publish the staged version before relying on the public form lifecycle.

For a local prototype, opt in explicitly with `<Fillo.Form renderOnly ...>` or `<FilloForm form={yourForm} renderOnly />`. It cannot save responses or upload files. The code-backed `FilloForm` props otherwise require `client`; `skipValidation` remains an internal builder/test path, not something to collect production responses with.

Keep the client and form definition outside the render function, or memoize them. Recreating both on every render adds avoidable work and can hide lifecycle errors.

## Style and verify

Use the `theme` or `appearance` props for tokens and named slot classes; Tailwind can target state like `data-[invalid]` and `data-[selected]`. Check focus order, errors, pending submission, success, dark surfaces, and what happens when the component unmounts mid-request.

## Try it

[Start with a prompt](/start?from=guide-react-form) and your coding agent builds the first form, staged for your review — or [open the editor](/new).

## Related

- [Custom layout example](/examples#custom-layout): Compare the default renderer with host-owned React markup.
- [Code-defined forms](/docs/authoring): Stage and publish a typed schema.
- [Custom UI](/docs/custom-ui): Replace fields or own the full layout.
- [Respondents and identity](/docs/respondents): Pass server-signed account context.
