# Fillo > Forms inside your app, with your UI. Design forms in the builder or define them in code, then render them as real controls in React, Vue, Svelte, or plain browser JavaScript — no iframe or hosted form page. Validation, multi-page logic, file uploads, conditional logic, responses, exports, and webhooks are handled for you. ## Choose the package - React or Next.js: use `@usefillo/react` - Vue, Svelte, Astro, vanilla browser JavaScript, or any other framework: use `@usefillo/dom` ## Install for React / Next.js ``` npm install @usefillo/react ``` ## Render a form built in the editor The form's ID is shown in its Share panel. The form must be Published. ```tsx import { FilloForm, createClient } from "@usefillo/react"; import "@usefillo/react/styles.css"; // optional — or style it yourself const client = createClient({ baseUrl: "https://fillo.so" }); export function Feedback() { return ; } ``` ## Install for other frameworks ``` npm install @usefillo/dom ``` Use `renderForm()` from your framework lifecycle hook or component mount function. ```ts import { defineForm, renderForm } from "@usefillo/dom"; import "@usefillo/dom/styles.css"; const form = defineForm({ id: "onboarding", pages: [ { id: "p1", blocks: [ { id: "email", kind: "email", label: "Work email", required: true }, { id: "company", kind: "short_text", label: "Company name", required: true }, { id: "notes", kind: "long_text", label: "What should we know?" }, ]}, ], }); const instance = renderForm(document.querySelector("#formwork-form"), { form, onSubmit: async (data) => console.log(data), }); // instance.setValue("email", "jane@acme.co"); // await instance.submit(); // instance.destroy(); ``` ## No build step / script tag ```html
``` ## Define a form in code (no editor) `defineForm` registers the form in your workspace the first time it renders. Get a publishable key (pk_...) from Settings. ```tsx import { FilloForm, createClient, defineForm } from "@usefillo/react"; const client = createClient({ baseUrl: "https://fillo.so", key: "pk_your_key" }); const form = defineForm({ id: "beta-feedback", pages: [ { id: "p1", blocks: [ { id: "what", kind: "long_text", label: "What were you trying to do?" }, { id: "score", kind: "linear_scale", label: "How likely are you to recommend us?", min: 0, max: 10 }, { id: "shot", kind: "file_upload", label: "Screenshot (optional)" }, ]}, ], }); ; ``` ## Where do responses go? - With a `client` (formId or defineForm): responses post to Fillo — view them in the dashboard, collect uploads, export CSV, or stream them to a webhook. - Pass `onSubmit={(data) => ...}` to handle the data yourself instead. ## Styling Quick tokens via the `theme` prop: `{ primary, background, text, radius, fontFamily }`. For more, write CSS or Tailwind against the `fw-*` classes — the SDK ships its defaults in a lower CSS cascade layer, so your rules always win. Every field carries `data-field`; every choice row carries `data-option`. ## Your own layout (advanced) To place fields yourself with your own markup between them, use the headless provider instead of ``: ```tsx import { FilloProvider, FormField, useField } from "@usefillo/react"; ``` It runs validation, logic, uploads and submit, but renders no layout — you place each `` and can render any field from scratch with `useField()`. ## Field kinds short_text, long_text, email, url, phone, number, select, multi_select, dropdown, checkbox, rating, linear_scale, ranking, matrix, signature, date, file_upload, hidden, custom. Content blocks: heading, paragraph, divider. ## Full docs https://fillo.so/docs/embed