# Context and placements

Tell OneStar the app version, platform, plan and cohort, name each placement, and read loads, starts and finishes per place.

Results can split and filter answers by the app version, the platform, the person's plan and cohort, and the place on your site the form sits, but only when your page says them. This page shows how to say them, what the widget adds by itself, and how Results counts how many people who saw a form answered it.

## Context with onestar.set

```html index.html
<script>
  window.onestar = window.onestar || { q: [] };
  onestar.q.push(["set", { app_version: "2.4.1", platform: "web", plan: "pro", cohort: "2026-10" }]);
</script>
<script src="https://embed.onestar.sh/v1/loader.js" async></script>
```

The widget reads the context when it saves the person's first answer, so call `set` before that, before or after the loader. Later steps of the same answer keep the context it started with. Each call adds to or replaces earlier keys. Five keys are kept and everything else is dropped:

| Key | What to put in it | Rules |
|---|---|---|
| `app_version` | Your app or site version, such as `2.4.1` | Up to 40 characters. |
| `platform` | Your word for where it runs, such as `web`, `ios`, `android` or `desktop` | Up to 40 characters. |
| `locale` | The person's language, such as `en-GB` | Up to 20 characters. Set automatically from the browser; your value wins. |
| `plan` | The person's plan in your product, such as `pro` | A short label. |
| `cohort` | Any group you want to compare, such as a signup month `2026-10` or a test arm `b` | A short label. |

Values are strings or numbers, trimmed and cut to 40 characters.

### plan and cohort are stated, not checked

`plan` and `cohort` are your page's own word. OneStar cannot check them, so Results labels them **Plan (from the page)** and **Cohort (from the page)** and keeps them apart from anything verified.

They must be short labels: letters, digits, spaces, dots, dashes and underscores, starting with a letter or digit, up to 40 characters. Anything else, such as an email address or a sentence with punctuation, is dropped, not refused. A name or a user id would still pass the rule, so keep these to plan names and group labels.

When you need facts about the person that you can stand behind, put them in a signed token instead. Traits in a token your server signed are checked, and Results splits by them under **Trait**. See [Signed in users](https://onestar.sh/docs/feedback/identify-users.md).

## What the widget adds itself

With every answer, the widget also sends:

- the page's path, without its query string or fragment (those often hold tokens and email addresses), up to 200 characters,
- the origin of the referring page, never its full address,
- the browser's language as `locale`, unless you set one.

Nothing else is collected about the page or the person. See [Allowed sites and security](https://onestar.sh/docs/feedback/security.md).

## Placements

A placement is your name for where a form sits. Give each element its own with the `placement` attribute:

```html
<onestar-feedback form="f_hemsz66yupbd76d2" mode="inline" placement="checkout"></onestar-feedback>
<onestar-feedback form="f_hemsz66yupbd76d2" mode="popover" placement="help-menu"></onestar-feedback>
```

Without a name, answers and loads count under the site and the mode, so two inline forms on one site look like one place. With names, Results shows each one on its own line.

- A name is lower case letters, digits, dashes and underscores, starting with a letter or digit, up to 40 characters.
- It is lower cased and spaces become dashes, so `Help Menu` becomes `help-menu`. A name with anything else, such as a dot or a slash, counts as no name.
- A form keeps a limited number of placement names. Past it, answers from a new name count under the site without a name.
- In an app's web view, pass the name as the `placement` query parameter; it defaults to `app`. See [Native apps](https://onestar.sh/docs/feedback/native-apps.md).

The same form can run with different modes and placements at once. Each answer records the site, the mode and the placement it came from.

## Seen to answered

On the form's **Results**, the **Where it runs** card has a **Seen to answered** view. For each place it shows how many times the form loaded, how many answers were started and how many finished, and the finish rate:

| Column | What it counts |
|---|---|
| **Loads** | Each time a page drew the form: an inline form as it came near the screen, a popover, slide-in or modal when it opened. Once per element per page view. |
| **Started** | Answers from their first tap. The widget saves the first answer at once, so a person who answered one question and left counts here. |
| **Finished** | Answers sent whole. |
| **Finish rate** | Finished as a share of loads. |

A few rules keep the three numbers comparable:

- A load is a count only: the day, the site the browser named, the mode and the placement. Nothing about the visitor, and nothing stored in their browser. The site is what the browser said, and OneStar does not check it.
- Every version of the form counts, and test answers never do. Loads on `localhost` and loads of a form in test mode are not counted either.
- Only the window filter applies to this view. The other filters on the page (placement, platform and the rest) do not change it.
- The view starts on the first day a load was counted for the form, so a form older than load counting shows only the days since then.
- Answers from your own UI (`onestar.submit`) and imported answers have no loads, so they stay out of this view. Conversations shown with `mode="thread"` or `<onestar-inbox>` are not loads.

The form's own page and the page for apps count too, under OneStar's site.

Switch to **Every place** to see each place with its mode, its answers and its last answer. From either view you can read the answers from a place or filter the page to it.

## Splits and filters on Results

Once answers carry context, Results can narrow to it and compare across it:

- Filter the whole page by **Placement**, **Platform**, **App version**, **Plan** or **Cohort**.
- In **By segment**, split answers by **Platform**, **App version**, **Placement**, **Who**, **Channel**, **Plan (from the page)**, **Cohort (from the page)** or **Trait**, with the answers and the share of happy answers (or NPS) for each.

A filter appears once at least one answer carries a value for it. On Max, the [REST API](https://onestar.sh/docs/feedback/rest-api.md) takes the same filters and splits, and returns the load counts too.
