You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/how-to-guides/client-side-feature-flags.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ This guide shows how to set up a **JavaScript/TypeScript web application** using
6
6
7
7
## Prerequisites
8
8
9
-
1.**Create your variables** in the Logfire UI (Settings > Variables) and mark them as **external** — see [External Variables and OFREP](../reference/advanced/managed-variables/external.md)
9
+
1.**Create your variables** in the Logfire UI (**Runtime > Managed Variables**) and mark them as **External** — see [External Variables and OFREP](../reference/advanced/managed-variables/external.md)
10
10
2.**Create an API key** with the `project:read_external_variables` scope — this restricted scope is safe to use in client-side code since it only exposes variables you've explicitly marked as external
Copy file name to clipboardExpand all lines: docs/reference/advanced/managed-variables/external.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ There are two fundamentally different ways to read managed variables, and the ch
8
8
9
9
### Pull-Based (Logfire SDK)
10
10
11
-
When you use `logfire.variable.get()`(or the `.get()` method on a variable created with `logfire.var()`), the SDK **pulls the full variable configuration** from the server and evaluates it locally:
11
+
When you call `.get()` on a variable created with `logfire.var()`, the SDK **pulls the full variable configuration** from the server and evaluates it locally:
12
12
13
13
1. The SDK fetches all variable definitions, versions, labels, and rollout rules in a single request
14
14
2. A background thread polls for updates (or listens via SSE)
@@ -26,7 +26,7 @@ The OFREP endpoints take a different approach — every evaluation is a **server
26
26
2. The server evaluates the variable using the context and returns only the resolved value
27
27
3. The client never sees the full configuration, other versions, or rollout rules
28
28
29
-
This is less efficient (one network request per evaluation or batch), but the full configuration is **never exposed** to the client. A client would have to brute-force individual keys to discover what variables exist.
29
+
This is less efficient (one network request per evaluation or batch), but the full configuration is **never exposed** to the client. Single-flag evaluation returns only the requested variable's resolved value, while bulk evaluation returns resolved values for the variables the token is allowed to access.
30
30
31
31
**Requires:**`project:read_variables` or `project:read_external_variables` scope.
32
32
@@ -46,7 +46,7 @@ By default, variables are **internal** — they are only accessible with an API
46
46
|`project:write_variables`| Create, update, and delete variables and variable types |
47
47
48
48
!!! warning "API key scope and SDK access"
49
-
An API key with only the `project:read_external_variables` scope **cannot be used with `logfire.variable.get()`** or any of the pull-based SDK variable methods. The SDK's pull-based approach requires `project:read_variables` because it fetches the full configuration. The `project:read_external_variables` scope only grants access to the OFREP evaluation endpoints.
49
+
An API key with only the `project:read_external_variables` scope **cannot be used with `.get()` on variables created with `logfire.var()`** or any of the pull-based SDK variable methods. The SDK's pull-based approach requires `project:read_variables` because it fetches the full configuration. The `project:read_external_variables` scope only grants access to the OFREP evaluation endpoints.
50
50
51
51
### Setting a Variable as External
52
52
@@ -103,7 +103,7 @@ POST /v1/ofrep/v1/evaluate/flags
103
103
104
104
-`targetingKey` is required and is used for deterministic rollout selection.
105
105
- Any additional fields in `context` become attributes for conditional rules.
106
-
- The OFREP response maps labels to the `variant` field for compatibility with OpenFeature clients.
106
+
- The OFREP response maps the selected label or target to the `variant` field for compatibility with OpenFeature clients. For example, the variant can be a label such as `production`, the automatic `latest` target, or `null` when no remote value is resolved.
107
107
108
108
**Caching (bulk endpoint):**
109
109
@@ -114,9 +114,9 @@ These endpoints require an API key with the `project:read_variables` or `project
114
114
115
115
### Response Behavior
116
116
117
-
When the server resolves a variable successfully, the OFREP response includes the resolved `value`, a `variant` (the label name), and `reason: "TARGETING_MATCH"`.
117
+
When the server resolves a variable successfully, the OFREP response includes the resolved `value`, a `variant`, and a `reason` such as `"STATIC"`, `"SPLIT"`, or `"TARGETING_MATCH"`.
118
118
119
-
When no value can be resolved — either because the variable has no versions, or because no label matches the evaluation context (e.g., rollout weights sum to less than 1.0 and no latest version fallback exists) — the server returns:
119
+
When no remote value can be resolved — for example, because the variable has no versions yet or routing selects **Code default** — the server returns:
Copy file name to clipboardExpand all lines: docs/reference/advanced/managed-variables/index.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -39,11 +39,11 @@ And two labels pointing to those versions:
39
39
40
40
To roll out v3 to everyone, just move the `production` label from v2 to v3. To roll back, move it back to v2. No new versions need to be created — the label is just a pointer.
41
41
42
-
!!! tip "Code default fallback"
43
-
If no labels are configured in the rollout, or if rollout weights sum to less than 1.0, the remaining traffic uses the **code default** (the `default` value passed to `logfire.var()`). To direct remaining traffic to the latest version instead, create a label that references `latest` and include it in your rollout.
42
+
!!! tip "Latest and Code default"
43
+
In the Logfire UI, every variable has an automatic `latest` entry that points to the most recently created version. New variables start by routing traffic to `latest`, but `latest` has no value until you create the first version. The **Targeting** tab also shows **Code default**, which is the `default` value passed to `logfire.var()`in your application.
44
44
45
45
!!! note "Code default as safety net"
46
-
The `default` value you pass to `logfire.var()` serves as an always-available fallback hard-coded into your source code. If no versions have been created yet, or if the remote configuration is unreachable due to a networking issue, or if a remote value fails validation against your type, the SDK returns the code default instead of raising an error. This means your application always has a working value — the remote configuration improves it, but never breaks it.
46
+
The `default` value you pass to `logfire.var()` serves as an always-available fallback hard-coded into your source code. If no remote value can be resolved, if the remote configuration is unreachable due to a networking issue, or if a remote value fails validation against your type, the SDK returns the code default instead of raising an error. This means your application always has a working value — the remote configuration improves it, but never breaks it.
Copy file name to clipboardExpand all lines: docs/reference/advanced/managed-variables/ui.md
+15-14Lines changed: 15 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,11 +1,11 @@
1
1
# Managing Variables in the Logfire UI
2
2
3
-
The Logfire web UI provides a complete interface for managing your variables without any code changes. You can find it under **Settings > Variables** in your project. The page includes two tabs:
3
+
The Logfire web UI provides a complete interface for managing your variables without any code changes. You can find it under **Runtime > Managed Variables** in your project. The page includes two tabs:
4
4
5
5
-**Variables**: browse, create, and manage your managed variables
6
6
-**Types**: define reusable JSON schemas for custom variable types
7
7
8
-
Clicking a variable opens its **detail page**, which has four tabs: **Values**, **Targeting**, **History**, and **Settings**.
8
+
Clicking a variable opens its **detail page**, which has **Values**, **Targeting**, **Optimize**, and**History** tabs. Users with write access also see**Settings**.
9
9
10
10

11
11
@@ -31,26 +31,28 @@ For **Custom Types**, the schema is derived from the type and shown read-only; e
31
31
32
32
The **Values tab** is the primary interface for viewing and editing your variable's content. It combines label management with value editing in a single view.
33
33
34
-
The left sidebar shows all labels (both active and inactive), while the right panel displays the value for the selected label. Each label in the sidebar shows its name and what it points to (e.g., a version number, another label, or "latest").
34
+
The left sidebar shows the automatic `latest` entry plus all labels (both active and inactive), while the right panel displays the value for the selected entry. Each label in the sidebar shows its name and what it points to (e.g., a version number, another label, `latest`, or **Code default**).
35
35
36
-
- Select a label in the sidebar to view its current value
36
+
- Select `latest` or a label in the sidebar to view its current value
37
37
- Click the **copy** button to copy the displayed value to your clipboard
38
38
- Click the **compare** button to diff the selected label's value against another label — useful for reviewing differences between production and staging prompts, for example
39
-
- Click **Edit** to modify the value, then **Save new version** to create a new version and assign it to the selectedlabel
40
-
- Click **Add label** to create new labels pointing to a specific version, another label, the latest version, or the code default
39
+
- Click **Edit** to modify the value, then **Save new version** to create a new version. When `latest` is selected, the new version becomes the latest version. When a label is selected, the new version is assigned to that label.
40
+
- Click **Add label** to create new labels pointing to a specific version, another label, `latest`, or **Code default**
**Labels** are mutable pointers to specific versions. They work like Docker tags or git branch names — you can move them to point at any version at any time.
44
+
`latest` is always present and points to the most recently created version. A new variable has no versions yet, so `latest` has no value until you create the first version.
45
+
46
+
**Labels** are mutable pointers to specific versions or targets. They work like Docker tags or git branch names — you can move them to point at any version, another label, `latest`, or **Code default** at any time.
45
47
46
48
Common label patterns:
47
49
48
50
-**`production`** / **`staging`** / **`canary`**: Environment-based labels for gradual rollouts
If a variable has no labels configured in its routing, your application serves the code default (the `default` value passed to `logfire.var()`). To serve the latest version instead, create a label that references `latest`and include it in your routing.
54
+
!!! note "Code default"
55
+
**Code default** is the `default` value passed to `logfire.var()` in your application. Use it when you want some traffic to ignore remote versions and keep using the value from code.
54
56
55
57
## Browsing Version History
56
58
@@ -70,13 +72,12 @@ The **History tab** lets you browse all saved versions:
70
72
71
73
## Configuring Label Routing
72
74
73
-
The **Targeting tab > Default** section controls what percentage of requests receive each labeled version. The weights are entered as percentages (0–100%) and must sum to 100% or less:
75
+
The **Targeting tab > Default** section controls what percentage of requests receive each label, `latest`, or **Code default**. The editable weights are entered as percentages (0-100%) and must sum to 100% or less. **Code default** is the remaining percentage after label and `latest` weights are allocated.
74
76
75
77
- Set `production` to `90` and `canary` to `10` for a 10% canary deployment
76
78
- Set `control` to `50` and `treatment` to `50` for a 50/50 A/B test
77
-
- To send some traffic to the latest version, create a label that references `latest` and include it in the routing — for example, a `latest` label referencing latest at `10` and `control` at `50` sends 10% of traffic to the latest version, 50% to the control label, and the remaining 40% falls back to the code default
78
-
- If weights sum to less than 100%, the remaining percentage uses the **code default**
79
-
- If no labels are in the routing (empty), all traffic uses the code default
79
+
- Set `latest` to `10` and `control` to `50` to send 10% of traffic to the most recently created version, 50% to the control label, and the remaining 40% to **Code default**
80
+
- New variables start with `latest` at `100`, so all traffic uses the newest version once one exists
80
81
81
82
## Targeting with Conditional Rules
82
83
@@ -100,4 +101,4 @@ For example, to give enterprise customers the production experience:
The variable name in the UI must exactly match the `name` parameter in your `logfire.var()` call. If they don't match, your application will use the code default instead of the remote configuration.
104
+
The variable name in the UI must exactly match the `name` parameter in your `logfire.var()` call. If they don't match, your application will use **Code default** instead of the remote configuration.
0 commit comments