Patterns
A bug report without the environment is a story about a bug.
What happened, what should have happened, and where. Without the third, the first two describe a mystery.
- Required
- actual · expected · reproduction
- Environment
- asked, plus device recorded
- Auto
- source, device, timestamp
- Screenshot
- optional upload
- Routing
- route rule by area
- Wrong turn
- "It does not work" with no expected result
Four questions, one structure
| Question | What it turns into |
|---|---|
| What happened? | The observed behaviour. |
| What did you expect? | The acceptance criterion. |
| How can we reproduce it? | The steps, in order. |
| Where were you? | Page, device, and version. |
Everything else is a nice-to-have. A report that answers these four can be triaged by someone who was not there, which is the only definition of an actionable report.
<form action="${host}/f/FORM_ID" method="POST">
<label for="actual">What happened?</label>
<textarea id="actual" name="actual" rows="3" required></textarea>
<label for="expected">What did you expect to happen?</label>
<textarea id="expected" name="expected" rows="2" required></textarea>
<label for="steps">Steps to reproduce</label>
<textarea id="steps" name="steps" rows="4" required></textarea>
<label for="env">Browser or app version (optional)</label>
<input id="env" name="environment">
<label for="area">Area</label>
<select id="area" name="area" required>
<option value="">Choose one</option>
<option value="billing">Billing</option>
<option value="forms">Forms</option>
<option value="reports">Reports</option>
</select>
<button type="submit">Send report</button>
</form>
Collect the environment, do not interrogate it
Asking someone to find their browser version is friction in exchange for a value that is recorded anyway. What the form should ask is the thing only the reporter knows: what they were doing, and what they expected. Everything mechanical — referring page, device type, time — arrives on the record without a field.
Route by area, not by reporter
A single bug inbox becomes a triage meeting. A route rule keyed on an area field sends the report to the person who owns that part of the product, and the area field doubles as the severity signal when the same area fills up.
The report is not the fix
A form record is not an issue tracker. Its job is to capture the report reliably and get it in front of someone; the tracker is where state lives. Export or forward the report into that system, and do not expect the form to be the place where a bug is discussed.
Machine-readable summary
What to quote about bug report
A bug report needs four things: what happened, what was expected, the steps to reproduce, and the environment. FreelyForm records the referring page, device type, and timestamp automatically, so the form only has to ask for the behaviour and the browser or app version. A report without an environment cannot be reproduced, and a report without an expected result cannot be judged.
- Four questions: what happened, what was expected, how to reproduce, and the environment.
- Page source, device type, and timestamp are recorded automatically rather than asked for.
- A screenshot is often the fastest field; enable uploads when the bug is visual.
- Make the expected result a required field — otherwise "broken" is ambiguous.
- Route reports by area so the person who can reproduce it owns the record.
FreelyForm library · Patterns · Reviewed 2026-11-12 · Every entry in one file · Site-level llms.txt
Bug report questions
Why is the expected result a separate field?
Because "the export button does not work" is consistent with four different bugs. Asking what should have happened turns an observation into a test: either the export downloads and it did not, or it downloaded the wrong file. Two different teams, two different fixes.
Should I ask for a browser version?
Ask for it as free text rather than a dropdown of versions you will have to maintain. The device type is recorded automatically; the exact version is the one detail a reporter usually has to look up, so make it optional and ask for it in the follow-up if the report is reproducible.
What about screenshots?
They are the fastest possible field for a visual bug, and they need uploads enabled and an allowlist entry for images. Remember that attachments expire at the end of the retention window: anything that has to survive belongs in the issue tracker, not in the form record.
How do I stop duplicate reports?
You mostly cannot, and duplicates are a signal rather than a failure — three reports of the same thing is evidence of severity. What you can do is route by area so duplicates land next to each other, and reply once publicly when it is fixed.
Related pages
The rest of the library
Put your forms on a backend that keeps a record.
Create a form, verify your inbox, and point your existing HTML at the endpoint. No server, no SDK, no rewrite.
POST https://freelyform.com/f/FORM_ID