Server reactivity
Once a handler has changed the state (cf.Server actions), here is what re-renders on screen, and how to control it.
The automatic re-render
A `@refreshable(deps=[…])` zone declares the states it reads. When a handler mutates one of them, the zone is re-rendered automatically — no refresh to call.@refreshable(deps=[Cart])
def cart_summary() -> None:
ui.text(f"{len(Cart().items)} items")
def add_to_cart(product_id: str) -> None:
Cart().items.append(product_id)
# cart_summary re-renders: Cart is in its deps
Mutation = re-render
At the end of an action, the server compares the state before and after — including in-place modifications (`items.append(...)`, `d[k] = v`). Every zone whose `deps=` changed is re-rendered and sent back to the browser.Conversely, if a handler changes no state declared in a `deps=`, no zone is re-rendered — the round trip brings back nothing to refresh.Triggering by hand — refresh()
`refresh(zone)` forces a zone's re-render. Useful when the change does not come from a declared state, or from somewhere that is not an action handler. It can also be addressed by its `name`.from bretzel import refresh
def reload_prices() -> None:
fetch_latest()
refresh(price_table) # by the zone
# or: refresh("price_table") # by its name=
Realtime between clients — broadcast
`deps` and `broadcast` are two ORTHOGONAL lists, and the question they ask is the same: who changes this state?• ME → `deps`. The zone is re-rendered in the action's response: one round trip, one swap.• THE OTHERS → `broadcast`. An SSE signal, then a refetch: two round trips, but the tab that did nothing follows.• BOTH → both lists. It is not a redundancy: it says “instant for me, pushed to the others”.
@refreshable(deps=[Cart]) # local
@refreshable(broadcast=[Queue]) # I never
# change it
@refreshable(deps=[Presence], broadcast=[Presence],
name="online_users") # both
What crosses is only a SIGNAL: every client refetches in its own context, no data passes from one client to another. `name=` gives a stable address for `refresh("…")`.What next
The reactivity that lives in the browser, with no round trip:Client reactivity →