Module

server.fragment_dispatch

Block-fetch dispatcher — URL-addressable blocks for any route.

GET/_frag{path}?_b={block} matches the underlying route for {path}, invokes its handler, and returns only the named kida block. Makes every block of every page a first-class, cache-friendly resource without requiring the handler to know about fragment addressing.

URL scheme (RFC 0.2):

  • /_frag/ prefix is reserved and collision-checked at app.check()time.
  • Block name is a query param_b so the {path:path}doesn't swallow it.
  • Trailing-slash variants are attempted transparently (/foo and /foo/).

Why a query string? The underlying path may itself be a{path:path} catch-all (/docs/{slug:path}) — encoding the block as a suffix segment would be ambiguous. Query strings are CDN-friendly withoutVaryconfig.

Handler result coercion:

  • Template / Page / LayoutPage → re-packed as Fragmentwith the requested block name and handler context.
  • Fragment→ returned as-is (handler already scoped to one block).
  • Anything else → 400; the block-fetch URL is not meaningful for it.

No live-block registration is required at this layer — this is the raw mechanism. Sprint 2's@app.live_blockdecorator adds the allowlist + freeze-time rewriting that turns a regular block into a true live block.

Classes

FragmentDispatchTarget 3
Resolved target route for a ``/_frag`` request.

Resolved target route for a/_fragrequest.

Attributes

Name Type Description
match RouteMatch
request Request
block_name str
_BadFragmentRequest 1
400 — the fragment URL is well-formed but can't be dispatched.

400 — the fragment URL is well-formed but can't be dispatched.

Methods

Internal Methods 1
__init__ 1
def __init__(self, detail: str) -> None
Parameters
Name Type Description
detail

Functions

fragment_url 2 str
Build the block-fetch URL for a ``(route_path, block_name)`` pair. ``route_pat…
def fragment_url(route_path: str, block_name: str) -> str

Build the block-fetch URL for a(route_path, block_name)pair.

route_pathis the underlying user-route path. Leading slashes are normalised; trailing slashes are preserved (they affect the handler's view ofrequest.path). block_nameis URL-safe as-is — the kida block-name grammar is a subset of what URLs accept.

Usage::

fragment_url("/docs/intro", "recent_updates")
# "/_frag/docs/intro?_b=recent_updates"

Also available as a template global of the same name when the app is compiled — use it in htmx attributes::

<div hx-get="{{ fragment_url('/docs/intro', 'recent_updates') }}"
     hx-trigger="load">loading…</div>
Parameters
Name Type Description
route_path str
block_name str
Returns
str
_normalize_target_path 1 str
Build the underlying path from the catch-all segment. The catch-all strips the…
def _normalize_target_path(encoded: str) -> str

Build the underlying path from the catch-all segment.

The catch-all strips the leading/_frag/. We put back a single leading slash. Trailing-slash handling is left to the caller (we try both).

Parameters
Name Type Description
encoded str
Returns
str
_encoded_path_from_fragment_request 1 str | None
Return the encoded target path segment for a fragment-dispatch URL.
def _encoded_path_from_fragment_request(path: str) -> str | None
Parameters
Name Type Description
path str
Returns
str | None
is_fragment_dispatch_request 1 bool
Whether *request* addresses the block-fetch endpoint.
def is_fragment_dispatch_request(request: Request) -> bool
Parameters
Name Type Description
request Request
Returns
bool
resolve_fragment_dispatch_target 2 FragmentDispatchTarget
Resolve ``/_frag{path}?_b=...`` before middleware policy runs.
def resolve_fragment_dispatch_target(router: Router, request: Request) -> FragmentDispatchTarget
Parameters
Name Type Description
router Router
request Request
Returns
FragmentDispatchTarget
_coerce_to_fragment 2 Fragment
Convert a handler's return value into a ``Fragment`` for *block_name*. Raises …
def _coerce_to_fragment(result: Any, block_name: str) -> Fragment

Convert a handler's return value into aFragmentfor block_name.

Raises_BadFragmentRequestfor streaming / mutation / redirect results — those have no single block to extract.

Parameters
Name Type Description
result Any
block_name str
Returns
Fragment
_dispatch_fragment 2 Fragment
Match the underlying route, invoke its handler, re-pack as a Fragment.
async
async def _dispatch_fragment(app: App, request: Request) -> Fragment
Parameters
Name Type Description
app App
request Request
Returns
Fragment
make_fragment_dispatch_pending_route 1 PendingRoute
Return a ``PendingRoute`` that dispatches ``/_frag{path}?_b=block``. The closu…
def make_fragment_dispatch_pending_route(app: App) -> PendingRoute

Return aPendingRoute that dispatches /_frag{path}?_b=block.

The closure captures app so the handler can reach the compiled router and provider registry at request time.

Parameters
Name Type Description
app App
Returns
PendingRoute