> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stage.systems/llms.txt
> Use this file to discover all available pages before exploring further.

# Forms setup

> Give a site forms: the question renderers, the overlay, the preview canvas, and the schema entries. Question types are platform constants; their look is the site's.

A form is an article-like document: its own tables, a body that is a component stream, the same inline editor. Six **question types** are platform constants because the submit endpoint validates answers against the stored definition. Their **renderers** are per site like any component. What the builder sees is in [Guides: Forms](/editing/forms).

## The pieces

| Piece                                                                | Where                | Notes                                                                                     |
| -------------------------------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------- |
| `Field`                                                              | `components/forms/`  | The shared question shell: label anchor, required marker, error slot. Restyle mostly here |
| `ShortText`, `LongText`, `Email`, `Choice`, `Checkboxes`, `Dropdown` | `components/forms/`  | One renderer per question type                                                            |
| `PageBreak`                                                          | `components/forms/`  | Renders nothing visible. The fill runtime derives pages from marker positions             |
| `FormBody`                                                           | `components/forms/`  | The render loop plus the fill runtime (paging, token, submit)                             |
| `FormOverlay`                                                        | `components/global/` | Every published form as a full-screen dialog, mounted from the base layout                |
| `preview/f/[slug].astro`                                             | `pages/`             | The gated edit canvas. It must mirror the overlay's composition exactly                   |
| `preview/blocks.astro`                                               | `pages/`             | Pre-rendered block prototypes for instant `/` inserts                                     |

Register the six question types and `page-break` in the registry, and export `stageFormMeta` from the anchors file.

## The address

There is no public form route. A form's address is `/?form=<slug>`. Any same-origin link carrying that parameter opens the overlay in place, and the parameter auto-opens on arrival, so a campaign link or QR code lands with the form open. `window.openStageForm(slug)` is the programmatic API. Inside the admin canvas the same link opens the form's edit canvas instead.

Two other presentations are per-site builds: an in-page document with normal chrome, or a full-screen takeover. Whichever a design uses, the preview route mirrors it.

## The schema

```ts theme={null}
forms: {
  basePath: "f",           // names the PREVIEW segment
  menu: [ /* the question types with their starters */ ],
},
"question-choice": {
  notch: [],               // the add is a ghost row, not a section tab
  form: [{ key: "required", label: "Required", type: "toggle" }],
  arrays: {
    "props.options": { kind: "inline", addLabel: "Add new option", reorderable: true, noun: "option",
      form: [{ key: "label", label: "Option", type: "text", required: true }] },
  },
},
```

A dropdown's options are edited from its cog (`type: "list"`), because native `<option>` elements cannot host canvas chrome. The email question has no cog: its `required` is locked.

## Submitting

Submitting requires JavaScript by design. The page fetches a single-use token bound to the org with a minimum age of two seconds; the submit sends it with the answers. The runtime reads the API base and site domain from `window` globals the base layout sets. The API validates against the stored definition, checks the email, stores the response, bridges it to the Inbox, and sends notifications to the addresses in org settings.

## Runtime hooks

| Hook                         | Use                                                                        |
| ---------------------------- | -------------------------------------------------------------------------- |
| `window.openStageForm(slug)` | Open a form from your own script                                           |
| `stage:form-open` event      | Dispatched when the overlay opens; the runtime warms the token and focuses |
| `astro:page-load`            | The runtime re-binds after client-side navigation                          |

## Next steps

<CardGroup cols={2}>
  <Card title="Tracking" href="/developers/analytics/tracking">
    How a submission becomes an enquiry in the funnel.
  </Card>

  <Card title="Page schemas" href="/developers/structure/schemas">
    The schema reference.
  </Card>
</CardGroup>
