Skip to content
All templates

Feedback 2 steps · 12 fields

Bug report

Steps to reproduce, expected and actual result, environment and severity.

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 · 133 lines
{  "id": "bug-report",  "title": "Report a bug",  "submit": { "label": "Send report" },  "steps": [    {      "id": "bug",      "title": "What happened",      "fields": [        {          "key": "summary",          "type": "text",          "label": "Short summary",          "validation": { "required": true, "maxLength": 120 }        },        {          "key": "steps",          "type": "textarea",          "label": "Steps to reproduce",          "rows": 4,          "placeholder": "1. Go to…\n2. Click…\n3. See the error",          "validation": { "required": true }        },        {          "key": "expected",          "type": "textarea",          "label": "What did you expect to happen?",          "rows": 2,          "validation": { "required": true }        },        {          "key": "actual",          "type": "textarea",          "label": "What happened instead?",          "rows": 2,          "validation": { "required": true }        }      ]    },    {      "id": "environment",      "title": "Where it happened and how bad it is",      "fields": [        {          "key": "platform",          "type": "radio",          "label": "Where did it happen?",          "options": [            { "value": "web", "label": "Web browser" },            { "value": "macos", "label": "macOS app" },            { "value": "windows", "label": "Windows app" },            { "value": "ios", "label": "iOS app" },            { "value": "android", "label": "Android app" },            { "value": "other", "label": "Somewhere else" }          ],          "validation": { "required": true }        },        {          "key": "browser",          "type": "select",          "label": "Browser",          "show": [{ "field": "platform", "eq": "web" }],          "options": [            { "value": "chrome", "label": "Chrome" },            { "value": "safari", "label": "Safari" },            { "value": "firefox", "label": "Firefox" },            { "value": "edge", "label": "Edge" },            { "value": "other", "label": "Other" }          ],          "validation": { "required": true }        },        {          "key": "os",          "type": "select",          "label": "Operating system",          "show": [{ "field": "platform", "eq": "web" }],          "options": [            { "value": "macos", "label": "macOS" },            { "value": "windows", "label": "Windows" },            { "value": "linux", "label": "Linux" },            { "value": "ios", "label": "iOS" },            { "value": "android", "label": "Android" },            { "value": "other", "label": "Other" }          ]        },        {          "key": "version",          "type": "text",          "label": "App or browser version",          "placeholder": "Version 4.2.1 or Chrome 129"        },        {          "key": "severity",          "type": "radio",          "label": "How bad is it?",          "options": [            { "value": "blocker", "label": "I can’t do my work" },            {              "value": "workaround",              "label": "Annoying, but there’s a workaround"            },            { "value": "minor", "label": "Minor or cosmetic" }          ],          "validation": { "required": true }        },        {          "key": "frequency",          "type": "radio",          "label": "How often does it happen?",          "layout": "inline",          "options": [            { "value": "always", "label": "Every time" },            { "value": "sometimes", "label": "Sometimes" },            { "value": "once", "label": "Only once" }          ],          "validation": { "required": true }        },        {          "key": "recording",          "type": "text",          "label": "Link to a screenshot or screen recording",          "placeholder": "https://"        },        {          "key": "email",          "type": "email",          "label": "Email for follow-up",          "inputMode": "email"        }      ]    }  ]}

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