Build a React client intake form with file uploads

작성자

카테고리:

← 피드로
DEV Community · Jacob Funch · 2026-08-10 개발(SW)
Cover image for Build a React client intake form with file uploads

Jacob Funch

Client intake often requires two types of information: searchable answers and files for review. This Vite and React example collects both in the same response.

You can try the form without an account.

Ask only what you need

The example asks for:

  • the client’s name;
  • a work email address;
  • the result they need;
  • an optional target date;
  • up to five briefs or reference files.

Each answer should help someone prepare for the first call. Leave detailed discovery questions for the call.

Define the form

The form schema lives in the React app:

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

const intake = defineForm({
  id: "vite-client-intake",
  title: "Tell us about your project",
  description: "Tell us what you need, when you need it and which files will help us prepare.",
  pages: [
    {
      id: "intake",
      blocks: [
        { id: "name", kind: "short_text", label: "Your name", required: true },
        { id: "email", kind: "email", label: "Work email", required: true },
        {
          id: "outcome",
          kind: "long_text",
          label: "What result do you need?",
          required: true,
        },
        { id: "target-date", kind: "date", label: "Target date" },
        {
          id: "documents",
          kind: "file_upload",
          label: "Briefs or reference files (PDF, DOCX, PNG or JPG)",
          accept: [".pdf", ".doc", ".docx", ".png", ".jpg", ".jpeg"],
          maxFiles: 5,
        },
      ],
    },
  ],
  settings: { submitLabel: "Send project details" },
});

Enter fullscreen mode Exit fullscreen mode

Keep the form and field IDs after you collect the first response. Fillo uses them as stored answer keys. You can change labels and help text without changing the IDs.

The React app controls the route, layout, styles and what happens after submit. Fillo handles the schema, validation, uploads and responses. The SDK renders React controls in the page. It does not use an iframe.

Send files straight to storage

The browser sends each file to the storage connected to the Fillo workspace. The Vite app does not proxy the file through its own server. Storage credentials do not go into the browser bundle.

For client files, connect Google Drive, Box, Amazon S3 or an S3-compatible bucket. Some eligible new workspaces can use temporary Fillo storage while they test. It accepts files up to 10 MiB, with 100 MiB available per workspace. Completed files expire after seven days. Connect your own storage before you use the form for client work.

Run the preview

The example still shows the form when no publishable key is present:

const key = import.meta.env.VITE_FILLO_KEY;
const fillo = key ? createClient({ key }) : null;

export function IntakeForm() {
  return fillo ? (
    <FilloForm form={intake} client={fillo} showTitle={false} />
  ) : (
    <FilloForm form={intake} renderOnly showTitle={false} />
  );
}

Enter fullscreen mode Exit fullscreen mode

Preview mode lets you fill in the fields and see the success state. It does not send a response. File uploads stay disabled.

Run it locally:

git clone https://github.com/jacobfunch/fillo-vite-client-intake-starter.git
cd fillo-vite-client-intake-starter
npm install
npm run dev

Enter fullscreen mode Exit fullscreen mode

Test before you share it

Check these cases before a client uses the form:

  1. Leave each required field empty and check the error.
  2. Select a file type that the form does not accept.
  3. Test the file count and storage size limits.
  4. Interrupt an upload and try it again.
  5. Submit a test response and find its files in Fillo.
  6. Use the form with a keyboard and on a phone.
  7. Delete the test response and check what happens to its files.

The repository contains the source, screenshots and a checklist for coding agents. The setup guide explains storage and publishing in more detail.

To collect responses with this example, start with Fillo.

원문에서 계속 ↗

코멘트

답글 남기기