# `UtmParameters`

Where a visit came from, as marketing links carry it: source, medium and campaign.

Use it to record a campaign with a sign-up or an order. For a whole address, use [`Url`](/docs/types/type-url.md).

## Shape

| Field | Type | Required? |
|---|---|---|
| `source` | `Text` | Yes |
| `medium` | `Text` | Yes |
| `campaign` | `Text` | Yes |
| `term` | `Text` | No |
| `content` | `Text` | No |

Write every field when you build one, and give a field that isn't required as `none`.

## Example

```jadpo
UtmParameters {
    source: "mailing"
    medium: "email"
    campaign: "autumn_sale"
    term: none
    content: none
}
```

`text.parse(raw, as: UtmParameters)` reads one from text that comes from outside. Text that isn't one at all fails `malformed`, such as `utm_source=mailing`.

## Good to know

- As text, parameters must be in the standard's order, `utm_source` first.
- `==` tells you whether two are the same. `<` and `list.sort_by` don't take it, so sort by one of its parts instead.

## In JSON

An object of its parts, in a request, a response or `json.write`:

```json
{"source":"mailing","medium":"email","campaign":"autumn_sale","term":null,"content":null}
{"source":"search","medium":"cpc","campaign":"spring","term":"running shoes","content":"banner"}
```

When you read one, a field that isn't required may be left out, or sent as `null`.

## Details

<details>
<summary>Text form, storage, how it is shown, and operations</summary>

`UtmParameters` is in the group Web and network, and has been in Jadpo since 0.1.0.

### Text form

`text.from` writes one standard text form, the same form `text.parse` reads back: `utm_source=mailing&utm_medium=email&utm_campaign=autumn_sale` and `utm_source=search&utm_medium=cpc&utm_campaign=spring&utm_term=running%20shoes&utm_content=banner`.

### How it is stored

It is stored in 5 columns, each named for the field, `_` and its suffix. This is `utm_source=search&utm_medium=cpc&utm_campaign=spring&utm_term=running%20shoes&utm_content=banner`:

| Column | Type | Holds |
|---|---|---|
| `<field>_source` | `text` | `'search'` |
| `<field>_medium` | `text` | `'cpc'` |
| `<field>_campaign` | `text` | `'spring'` |
| `<field>_term` | `text` | `'running shoes'` |
| `<field>_content` | `text` | `'banner'` |

### How it is shown to people

`text.format(value, locale:)` shows it to people in their locale.

With `locale: Locale.en_gb`:

| Value | Shown |
|---|---|
| `utm_source=mailing&utm_medium=email&utm_campaign=autumn_sale` | `utm_source=mailing&utm_medium=email&utm_campaign=autumn_sale` |
| `utm_source=search&utm_medium=cpc&utm_campaign=spring&utm_term=running%20shoes&utm_content=banner` | `utm_source=search&utm_medium=cpc&utm_campaign=spring&utm_term=running%20shoes&utm_content=banner` |

### Operations

It also takes `text.parse`, `text.from`, `text.format`, `json.read`, `json.write` and `==`. [How every standard type behaves](/docs/every-standard-type-meets-one-contract.md) says how they work.

</details>
