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
// Client automatically finds elements by beam-id or beam-item-id
277
+
// Client automatically finds elements by stable identity
277
278
returnctx.render([
278
279
<divbeam-id="stats">Visits: {visits}</div>,
279
280
<divbeam-id="users">Users: {users}</div>,
@@ -306,7 +307,9 @@ export function updateDashboard(ctx: BeamContext<Env>) {
306
307
Notes:
307
308
308
309
-`beam-target` accepts any valid CSS selector (e.g. `#id`, `.class`, `[attr=value]`). Using `#id` targets is still fully supported.
309
-
- Auto-targeting (step 2) intentionally does **not** use plain `id="..."` anymore; it uses only `beam-id` / `beam-item-id`.
310
+
- Auto-targeting (step 2) uses stable element identity from the returned HTML root: `beam-id`, `beam-item-id`, or `id`.
311
+
- Auto-targeting intentionally does **not** use input `name` values, because they are often not unique enough for safe DOM replacement.
312
+
- Prefer `beam-id` for named UI regions and `beam-item-id` for repeated/list items. Use plain `id` when that already matches your markup structure.
310
313
- When an explicit target is used and the server returns a single root element that has the same `beam-id`/`beam-item-id` as the target, Beam unwraps it and swaps only the target’s inner content. This prevents accidentally nesting the component inside itself.
311
314
312
315
**Exclusion:** Use `!selector` to explicitly skip an item:
@@ -940,6 +943,21 @@ Use `beam-keep` to prevent an element from being replaced during updates. This k
940
943
941
944
Since the input isn't replaced, focus and cursor position are naturally preserved.
942
945
946
+
Beam matches kept elements by stable identity in this order:
947
+
948
+
-`beam-id`
949
+
-`beam-item-id`
950
+
-`id`
951
+
- unique form control `name` as a best-effort fallback
952
+
953
+
For the most reliable behavior, give kept elements a `beam-id`, `beam-item-id`, or `id`. If multiple inputs share the same `name`, Beam will not preserve by `name` alone.
954
+
955
+
Use cases:
956
+
957
+
-`beam-id`: shared UI regions like badges, panels, counters, and named state scopes
958
+
-`beam-item-id`: repeated records in feeds, tables, carts, and paginated lists
959
+
-`id`: one-off DOM anchors when the element already has a stable page-level ID
960
+
943
961
### Auto-Save on Blur
944
962
945
963
Trigger action when the user leaves the field:
@@ -1158,13 +1176,13 @@ Polling automatically stops when the element is removed from the DOM.
1158
1176
1159
1177
## Hungry Elements
1160
1178
1161
-
Elements marked with `beam-hungry` automatically update whenever any action returns HTML with a matching ID:
1179
+
Elements marked with `beam-hungry` automatically update whenever any action returns HTML with matching stable identity:
1162
1180
1163
1181
```html
1164
-
<!-- This badge updates when any action returns #cart-count -->
1165
-
<spanid="cart-count"beam-hungry>0</span>
1182
+
<!-- This badge updates when any action returns beam-id="cart-count"-->
1183
+
<spanbeam-id="cart-count"beam-hungry>0</span>
1166
1184
1167
-
<!-- Clicking this updates both #cart-result AND #cart-count-->
1185
+
<!-- Clicking this updates both #cart-result AND the hungry badge-->
1168
1186
<buttonbeam-action="addToCart"beam-target="#cart-result">Add to Cart</button>
1169
1187
```
1170
1188
@@ -1175,12 +1193,20 @@ export function addToCart(c) {
1175
1193
<>
1176
1194
<div>Item added to cart!</div>
1177
1195
{/* This updates the hungry element */}
1178
-
<spanid="cart-count">{cartCount}</span>
1196
+
<spanbeam-id="cart-count">{cartCount}</span>
1179
1197
</>
1180
1198
);
1181
1199
}
1182
1200
```
1183
1201
1202
+
Hungry matching checks identity in this order:
1203
+
1204
+
-`beam-id`
1205
+
-`beam-item-id`
1206
+
-`id`
1207
+
1208
+
For shared UI regions, prefer `beam-id`. For repeated records, prefer `beam-item-id`.
1209
+
1184
1210
---
1185
1211
1186
1212
## Out-of-Band Updates
@@ -1708,6 +1734,54 @@ Share state between different parts of the page. Named states (with `beam-id`) p
1708
1734
1709
1735
**Note:** Named states persist when the DOM is updated by `beam-action`. This means reactive state is preserved even when server actions update the page.
1710
1736
1737
+
#### Server-Driven Named State Updates
1738
+
1739
+
Server actions can update existing named state directly, without returning HTML. This is useful when the UI already has a `beam-state` scope and you only want to change its data.
1740
+
1741
+
Use `ctx.state(id, value)` for a single state update:
0 commit comments