# Aggregations


Flare groups spans so you can follow one thing over time, like how a product page has been performing this week. Browser spans end up in two of those groups, Browser pages and External HTTP requests. The PHP groups are on the [PHP aggregations page](/docs/protocol/traces/aggregations).

## Browser pages

Built from `browser_pageload`, `browser_navigation` and `browser_web_vital` spans.

| Attribute | Required |
|---|---|
| `http.route` | yes |
| `flare.entry_point.handler.identifier` | no |
| `flare.route.source` | no |

Pages are grouped by route and by kind. The kind comes from the span type: `browser_pageload` counts as `pageload`, `browser_navigation` as `navigation`. A `browser_web_vital` span always counts as `pageload`, because vitals only ever describe a document load.

That split matters because the two are not comparable. A page load includes the network request, parsing and the framework booting. A client-side navigation reuses all of it. Averaging them together would hide slow first loads behind fast route changes.

`flare.route.source` records whether the route came from a router (`route`) or from the raw path (`url`). It defaults to `url` when you leave it out.

A span without `http.route` is not grouped at all. You can still open the trace and look at it, but the page contributes nothing to the numbers.

`flare.entry_point.handler.identifier` carries the same route value and is what Flare shows as the label of the span in a trace. It takes no part in the grouping, so send both with the same value.

### What `browser_web_vital` adds

A `browser_web_vital` span is left out of the count, the average, the duration percentiles and the error rate. It only contributes its vital values, so sending one does not inflate your pageload count and its zero duration does not skew your timings.

## External HTTP requests

Built from `browser_fetch` and `browser_xhr` spans. There is no separate browser grouping for them: they use the same External HTTP type the PHP client's `php_http_request` uses.

Rows are keyed on the method, the host and the path, and the span type is not part of that key. So a browser request and a PHP request only share a row when they are the same method, host and path within the same project. That happens when your server-side rendering and your browser code both call the same endpoint. Otherwise they stay in separate rows.

| Attribute | Required |
|---|---|
| `url.full` | yes |
| `http.request.method` | yes |

Both are required. A span missing either one is skipped.

Flare reads the host and the path out of `url.full`. Sending `server.address` or `url.path` instead does not work, because the requirement is on `url.full` itself. You can still send `server.address`, it just is not what the grouping uses.

Before grouping, Flare strips UUIDs and numbers out of the path. `GET /api/orders/1234` and `GET /api/orders/5678` end up in the same group, so you see how that endpoint performs rather than one row per order.
