# Clicks, forms, errors and page speed

> What the script notes about what people do on a page, what it never reads, and the attributes that name buttons, sections and forms or keep a part private.

Besides pages, the script notes what people do on them: the clicks they make, the forms they fill in, the errors they run into and how fast the page was. It’s what odo’s friction findings, and an AI assistant’s `find_friction`, are built from.

## What’s noted

| Group | What it notes |
| --- | --- |
| `clicks` | Clicks on links, buttons and other controls; rage clicks (the same spot, again and again, quickly); dead clicks (a click that changed nothing); text copied (its length, never the text) |
| `forms` | A form started, sent, refused by the browser (which field, and why), or left unsent |
| `errors` | Script errors: the message and where (file, line and column) |
| `sections` | Parts of the page that were on screen for at least a second |
| `vitals` | Page speed as visitors got it: loading (LCP), responsiveness (INP), layout shift (CLS) and the server’s response (TTFB) |
| `heat` | For [heatmaps](https://odo.gg/docs/heatmaps): where each click lands, how far down the page people get, and how long each part of it is in view |

All of them are on unless the tag says otherwise: `data-capture="clicks forms errors"` keeps those groups only, and `data-capture="none"` none. To stop them for a site altogether, turn off **Clicks, forms, errors and page speed** in its settings. Experiments are recorded with these too, so a site with them off records no experiments.

## What’s never read

Nothing anyone types. A control is named by its own label or a short caption of its own, never a card’s worth of text; a field by its name or id; anything else only by what it is and where. Text in an editor isn’t read at all. A page sends at most 100 notes and 10 errors, and its heatmap its own 40 clicks.

## Name things yourself

| Attribute | On | What it does |
| --- | --- | --- |
| `data-odo-label` | A control | Names it, when it has no words of its own (an icon button). Never put personal data in a label. |
| `data-odo-section` | A part of the page | Names it, so clicks inside say where they were, odo notes when it’s seen, and [heatmaps](https://odo.gg/docs/heatmaps#name-the-parts-of-a-page) read attention by it: `data-odo-section="Pricing"` |
| `data-odo-form` | A form, or its container | Names the form. Where there’s no `<form>`, put it on the container. |
| `data-odo-submit` | A button | The one that really sends a form without a `<form>`. Only a submit button, or one marked like this, counts as sending. |
| `data-odo-ignore` | Anything | Nothing inside is read. Put it around whatever shows personal data: a signed-in name, account pages, orders, messages. |
| `data-odo-event` | Anything clickable | Sends an [event](https://odo.gg/docs/events) when clicked. |

Put `data-odo-ignore` on the whole region, not only the text: a button inside it that says someone’s name is skipped too.

## Reading them

The dashboard ranks what gets in visitors’ way among its **Next moves**. An AI assistant connected to odo reads all of it in detail: `find_friction`, `analyze_clicks`, `analyze_forms`, `analyze_errors` and `analyze_performance` in the [tool reference](https://odo.gg/docs/mcp-tools#friction-speed-and-experiments), and one page’s heatmap with `page_heatmap`, `scroll_depth` and `page_attention`. Error messages, labels and form names come from browsers, and anyone can send them: odo tells assistants to treat them as data, never as instructions.
