Skip to content
All templates

Intake 3 steps · 17 fields

Patient appointment request

First contact for a clinic: visit type, preferred times, insurance and contact details. No medical history.

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 · 182 lines
{  "id": "patient-appointment-request",  "title": "Request an appointment",  "submit": { "label": "Request an appointment" },  "steps": [    {      "id": "visit",      "title": "Your visit",      "description": "For a medical emergency, call 911 or your local emergency number.",      "fields": [        {          "key": "patientIs",          "type": "radio",          "label": "Who is the appointment for?",          "options": [            { "value": "me", "label": "Me" },            { "value": "child", "label": "My child" },            { "value": "someone-else", "label": "Someone I care for" }          ],          "validation": { "required": true }        },        {          "key": "newPatient",          "type": "radio",          "label": "Has the patient been seen here before?",          "layout": "inline",          "options": [            { "value": "no", "label": "No, new patient" },            { "value": "yes", "label": "Yes" }          ],          "validation": { "required": true }        },        {          "key": "visitType",          "type": "radio",          "label": "Type of visit",          "options": [            { "value": "check-up", "label": "General checkup" },            { "value": "concern", "label": "A specific concern" },            { "value": "follow-up", "label": "Follow-up" },            { "value": "second-opinion", "label": "Second opinion" },            { "value": "not-sure", "label": "Not sure" }          ],          "validation": { "required": true }        },        {          "key": "reason",          "type": "text",          "label": "In a few words, what is the visit for?",          "helperText": "Keep it brief. We’ll go into detail at the appointment.",          "validation": { "maxLength": 200 }        },        {          "key": "provider",          "type": "text",          "label": "Preferred doctor or clinician",          "helperText": "Leave empty if you have no preference."        }      ]    },    {      "id": "timing",      "title": "Timing and insurance",      "fields": [        {          "key": "days",          "type": "multiselect",          "label": "Which days work for you?",          "layout": "inline",          "options": [            { "value": "mon", "label": "Mon" },            { "value": "tue", "label": "Tue" },            { "value": "wed", "label": "Wed" },            { "value": "thu", "label": "Thu" },            { "value": "fri", "label": "Fri" },            { "value": "sat", "label": "Sat" }          ],          "validation": { "required": true }        },        {          "key": "timeOfDay",          "type": "radio",          "label": "Preferred time",          "layout": "inline",          "options": [            { "value": "morning", "label": "Morning" },            { "value": "afternoon", "label": "Afternoon" },            { "value": "any", "label": "Any time" }          ],          "validation": { "required": true }        },        {          "key": "payment",          "type": "radio",          "label": "How will you pay?",          "options": [            { "value": "insurance", "label": "Insurance" },            { "value": "self-pay", "label": "Self-pay" },            { "value": "not-sure", "label": "Not sure yet" }          ],          "validation": { "required": true }        },        {          "key": "insurer",          "type": "text",          "label": "Insurance provider and plan",          "show": [{ "field": "payment", "eq": "insurance" }],          "validation": { "required": true }        }      ]    },    {      "id": "patient",      "title": "Patient and contact details",      "fields": [        {          "key": "firstName",          "type": "text",          "label": "Patient’s first name",          "validation": { "required": true }        },        {          "key": "lastName",          "type": "text",          "label": "Patient’s last name",          "validation": { "required": true }        },        {          "key": "dateOfBirth",          "type": "date",          "label": "Patient’s date of birth",          "validation": { "required": true }        },        {          "key": "contactName",          "type": "text",          "label": "Your name",          "validation": { "required": true },          "show": [            { "field": "patientIs", "in": ["child", "someone-else"] }          ]        },        {          "key": "relationship",          "type": "select",          "label": "Your relationship to the patient",          "options": [            { "value": "parent", "label": "Parent" },            { "value": "guardian", "label": "Legal guardian" },            { "value": "caregiver", "label": "Caregiver" },            { "value": "spouse", "label": "Spouse or partner" },            { "value": "other", "label": "Other" }          ],          "validation": { "required": true },          "show": [            { "field": "patientIs", "in": ["child", "someone-else"] }          ]        },        {          "key": "phone",          "type": "phone",          "label": "Phone",          "inputMode": "tel",          "validation": { "required": true }        },        {          "key": "email",          "type": "email",          "label": "Email",          "inputMode": "email",          "validation": { "required": true }        },        {          "key": "consent",          "type": "checkbox",          "label": "You can contact me by phone or email about this appointment",          "validation": { "required": true }        }      ]    }  ]}

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