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

# Part 7: Computed fields

> Wire the four-level computed chain (utm_campaign, tagged_url, short_url, qr_code) that turns user input into a QR code automatically.

<Info>
  **What you'll learn:** what a computed field is, how one computed field can feed another, and how the four-level chain that turns user input into a QR code is wired.

  **What you'll build:** `utm_campaign` (Concatenation), `tagged_url` (Tagged URL), `short_url` (Short URL), and `qr_code` (QR Code), in that dependency order.

  **Prerequisites:** [Part 6: User-addable picklists](/tutorial/06-user-addable-picklists).
</Info>

## Why this matters

Every part up to here has been about what a user types. This part is the payoff: no user input, four new fields, and the shape of the final record. A campaign creator fills in a name, a goal, a country, a date, and a URL, and the system produces a canonical UTM campaign string, a fully tagged URL, a branded short URL, and a QR code, every time, without touching any of those values. When the marketing team says "our UTM format changed," you edit the `utm_campaign` setup once at the GM level and every future record follows. That is the leverage computed fields buy you.

## Concepts first

### Computed fields

A **computed field** has no input cell on the submission form. Its value is derived from other fields on the same row, recomputed as the user types (a live preview) and again authoritatively when the submission is saved. Computed fields are always required and cannot be edited by submitters; they can be hidden if you do not want them shown. The value is stored on the record once the submission is approved, so downstream systems read a computed field the same way they read any other.

### Dependency chains

A computed field's inputs can themselves be computed fields. When the row is saved, Terminus fills in each computed field as soon as its inputs are ready, repeating until every value settles. That is how `qr_code` can depend on `short_url`, which depends on `tagged_url`, which depends on `utm_campaign`: four levels deep, resolved in one pass. You never maintain an order; Terminus works it out from how the fields reference each other (and rejects a setup that would depend on itself).

### The four types used here

Terminus ships more computed field types than this tutorial covers. The four used in the Campaign URL Builder are:

* **Concatenation**: joins other fields' values with a separator.
* **Tagged URL**: takes a base URL and appends query parameters sourced from other fields.
* **Short URL**: creates a shortened link that redirects to a destination URL (here, the tagged URL).
* **QR Code**: generates a QR image whose payload is a Short URL.

Auto Number, Random, Constant, and Terminus ID are covered in the [other computed fields recipe](/recipes/other-computed-fields).

### The chain we're building

```mermaid theme={null}
flowchart LR
  A[goal, country, region<br/>launch_date, campaign_name] --> B[utm_campaign<br/>Concatenation]
  C[destination_url] --> D[tagged_url<br/>Tagged URL]
  B --> D
  D --> E[short_url<br/>Short URL<br/>slug mode: auto, editable]
  E --> F[qr_code<br/>QR Code]
```

Five user-input fields feed `utm_campaign`. `utm_campaign` plus `destination_url` feed `tagged_url`. `tagged_url` feeds `short_url`. `short_url` feeds `qr_code`. Build them in that order.

## Step-by-step

<Steps>
  <Step title="Create utm_campaign (Concatenation)">
    Open the `Marketing` GM and click **Create new field**. Name: `utm_campaign`. Type: **Concatenation**. Under **Field parts**, add, in order: `goal`, `country`, `region`, `launch_date`, `campaign_name`. **Separator**: `-`. Turn on **Remove extra separators**. Save.

    <Tip>
      **Why Remove extra separators:** it collapses runs of empty parts into a single separator. If a user leaves `region` blank, the output is `awareness-us-20261115-black_friday_2026` instead of `awareness-us--20261115-black_friday_2026`: one dash between parts, never two. (Its alternative, **Empty field replacement**, substitutes a placeholder for each empty part instead; you can use one or the other, not both.)
    </Tip>
  </Step>

  <Step title="Create tagged_url (Tagged URL)">
    Click **Create new field**. Name: `tagged_url`. Type: **Tagged URL**. **Base URL field**: `destination_url`. Add three parameters: `utm_medium` sourced from the `utm_medium` field, `utm_source` sourced from `utm_source`, and `utm_campaign` sourced from `utm_campaign`. Save. The parameter key on the left is what appears in the query string; the field on the right supplies the value. Parameter values are percent-encoded by default.
  </Step>

  <Step title="Create short_url (Short URL)">
    Click **Create new field**. Name: `short_url`. Type: **Short URL**. **Destination URL field**: `tagged_url` (the computed field you just created, one step up the chain). Leave **Domain** on your account default. Slug mode: **auto, editable**. Slug size: `8`. Save.

    <Tip>
      **Why auto, editable:** the system picks a random slug for every new record, but a reviewer can override it before approval if they want a memorable one. The slug size default is `10`; the tutorial uses `8` to match the example output. The [short URL slug modes recipe](/recipes/short-url-slug-modes) covers the other two modes (auto-only, never editable; manual-only, always typed by hand).
    </Tip>
  </Step>

  <Step title="Create qr_code (QR Code)">
    Click **Create new field** one last time. Name: `qr_code`. Type: **QR Code**. **Source field**: `short_url`. Save. The QR encodes the Short URL's redirect address, not the tagged URL directly, so if a Short URL is ever retargeted, every QR code already printed still works.
  </Step>
</Steps>

<Note>📸 Screenshot coming soon: part 07 computed field preview</Note>

## Check your work

* Four new computed fields exist on the `Marketing` GM: `utm_campaign`, `tagged_url`, `short_url`, `qr_code`.
* The GM now has twelve fields total: eight user-input (from Parts 3 to 6) plus the four computed ones.
* Each field's settings screen shows a live **preview**. Enter sample values for the user-input fields there and the preview updates as the chain resolves end to end.
* No field is on a taxonomy yet. That is still Part 8.

## What you just built

The full computed chain. The governance model now carries every rule needed to turn a handful of campaign inputs into a fully tagged, shortened, QR-coded link. Below is the chain with a sample submission's values flowing through it.

```mermaid theme={null}
flowchart LR
  subgraph Inputs[User inputs]
    G[goal = awareness]
    CY[country = us]
    RG[region = california]
    LD[launch_date = 20261115]
    CN[campaign_name = black_friday_2026]
    DU[destination_url = https://shop.acme.example/deals]
    UM[utm_medium = email]
    US[utm_source = newsletter]
  end
  G --> UC[utm_campaign<br/>awareness-us-california-20261115-black_friday_2026]
  CY --> UC
  RG --> UC
  LD --> UC
  CN --> UC
  DU --> TU[tagged_url<br/>https://shop.acme.example/deals?utm_medium=email&utm_source=newsletter&utm_campaign=awareness-us-california-20261115-black_friday_2026]
  UM --> TU
  US --> TU
  UC --> TU
  TU --> SU[short_url<br/>https://go.acme.example/aB3xK9q2]
  SU --> QR[qr_code<br/>QR of short_url]
```

Sample output for `campaign_name = "Black Friday 2026"`, `goal = awareness`, `country = us`, `region = california`, `launch_date = 2026-11-15`, `destination_url = https://shop.acme.example/deals`, `utm_medium = email`, `utm_source = newsletter`:

```text theme={null}
campaign_name = black_friday_2026
utm_campaign  = awareness-us-california-20261115-black_friday_2026
tagged_url    = https://shop.acme.example/deals?utm_medium=email&utm_source=newsletter&utm_campaign=awareness-us-california-20261115-black_friday_2026
short_url     = https://go.acme.example/aB3xK9q2
qr_code       = <QR of short_url>
```

(`go.acme.example` and the slug `aB3xK9q2` are illustrative. Your account has its own shortener domain, and each record gets its own slug.)

## Gotchas

* **A computed field needs its inputs filled to produce a value.** If `region` is blank, `utm_campaign` still computes (thanks to **Remove extra separators**), but if `destination_url` is blank, `tagged_url` has no base to attach parameters to and its preview stays empty until a URL is entered.
* **A QR Code's source must be a Short URL field, not a plain URL.** The **Source field** picker offers Short URL fields. Encoding a long tagged URL directly would bake the full query string into the image and defeat the point of the short link.
* **Short URLs are draft until the submission is approved.** The slug is reserved on the row and shown in the preview, but the redirect is not live until approval promotes the row to a record. Grabbing a QR code from an unapproved submission will not resolve yet. See the [submission pipeline](/concepts/submission-pipeline) for how a draft becomes a record, and the [short URL reference](/reference/fields/short-url) for the field itself.
* **Reordering Concatenation parts is a real change, not a display tweak.** If you swap `country` and `region` in `utm_campaign` after approved records exist, those old records keep `awareness-us-california-…`; only new records get the new order. There is no retroactive recompute, so pick the order carefully.

## Next up

[Part 8: Your first submission](/tutorial/08-first-submission). Assemble three taxonomies, set `filter_options` for real, and run a campaign from draft through to approved records. For tagged URLs in isolation, see the [tagged URL recipe](/recipes/tagged-url-utm).
