Skip to content
All templates

Intake 3 steps · 18 fields

Client onboarding

Billing details, key contacts, brand assets and access, collected once when a client signs.

Get a hosted link and a responses inbox in a minute. No backend, no credit card.

Or set it up yourself

Live preview

Form definition JSON · 155 lines
{  "id": "client-onboarding",  "title": "Welcome aboard",  "submit": { "label": "Finish onboarding" },  "steps": [    {      "id": "company",      "title": "Company and billing",      "fields": [        {          "key": "legalName",          "type": "text",          "label": "Legal company name",          "validation": { "required": true }        },        {          "key": "website",          "type": "text",          "label": "Website",          "placeholder": "https://"        },        {          "key": "billingAddress",          "type": "textarea",          "label": "Billing address",          "rows": 3,          "validation": { "required": true }        },        {          "key": "taxId",          "type": "text",          "label": "Tax ID",          "helperText": "EIN in the US, or your VAT or local tax number."        },        {          "key": "billingContact",          "type": "text",          "label": "Who handles invoices?",          "placeholder": "Name and role"        },        {          "key": "billingEmail",          "type": "email",          "label": "Email for invoices",          "inputMode": "email",          "validation": { "required": true }        },        {          "key": "poRequired",          "type": "radio",          "label": "Do you need a purchase order number on invoices?",          "layout": "inline",          "options": [            { "value": "yes", "label": "Yes" },            { "value": "no", "label": "No" }          ],          "validation": { "required": true }        },        {          "key": "poNumber",          "type": "text",          "label": "PO number",          "helperText": "Leave empty if you’ll send it later.",          "show": [{ "field": "poRequired", "eq": "yes" }]        }      ]    },    {      "id": "people",      "title": "Contacts",      "fields": [        {          "key": "contactName",          "type": "text",          "label": "Main contact",          "validation": { "required": true }        },        {          "key": "contactEmail",          "type": "email",          "label": "Main contact email",          "inputMode": "email",          "validation": { "required": true }        },        {          "key": "contactPhone",          "type": "phone",          "label": "Main contact phone",          "inputMode": "tel"        },        {          "key": "approver",          "type": "text",          "label": "Who signs off on work, if not the main contact?"        },        {          "key": "channel",          "type": "radio",          "label": "Where should we talk day to day?",          "options": [            { "value": "email", "label": "Email" },            { "value": "slack", "label": "Slack" },            { "value": "teams", "label": "Microsoft Teams" },            { "value": "calls", "label": "Scheduled calls" }          ],          "validation": { "required": true }        },        {          "key": "timezone",          "type": "text",          "label": "Time zone",          "placeholder": "City or UTC offset"        }      ]    },    {      "id": "assets",      "title": "Assets and access",      "fields": [        {          "key": "assets",          "type": "text",          "label": "Link to brand assets",          "placeholder": "https://",          "helperText": "Logo, fonts and guidelines. A shared folder or Figma link works."        },        {          "key": "access",          "type": "multiselect",          "label": "What will we need access to?",          "helperText": "We’ll send a secure way to share logins. Don’t paste passwords here.",          "options": [            { "value": "cms", "label": "Website CMS" },            { "value": "dns", "label": "Domain and DNS" },            { "value": "hosting", "label": "Hosting" },            { "value": "analytics", "label": "Analytics" },            { "value": "social", "label": "Social accounts" },            { "value": "ads", "label": "Ad accounts" }          ]        },        {          "key": "kickoff",          "type": "date",          "label": "Preferred kickoff date"        },        {          "key": "notes",          "type": "textarea",          "label": "Anything we should know before we start?",          "rows": 3        }      ]    }  ]}

Use it with the npm packages ​

Copy the JSON into a file in your app, install the renderer and pass the definition to it. The same JSON works with @formhaus/vue.

sh
npm i @formhaus/core @formhaus/react
tsx
import { FormRenderer } from '@formhaus/react';
import '@formhaus/core/style.css';
import definition from './form.json';

export function Form() {
  return (
    <FormRenderer
      definition={definition}
      onSubmit={(values) => console.log(values)}
    />
  );
}

See Getting started for validation, steps and custom components.

Formhaus is MIT licensed. Legal