Skip to main content
Fetch makes HTTP requests from the browser using the native fetch() API. Use it to call REST endpoints, load external data, or submit forms — anything that speaks HTTP without needing an MCP server in the middle. The response is parsed automatically — JSON becomes an object, everything else becomes a string. If result_key is set, the parsed response is written into client-side state, making it immediately available via {{ users }} interpolation. The on_success callback fires after a successful request, so you can confirm the result with a toast or trigger follow-up actions.

Classmethods

Each HTTP method has a dedicated classmethod with a tailored signature. GET accepts query params, while POST/PUT/PATCH accept a body.
GET with query params
from prefab_ui.rx import Rx

query = Rx("query")
Fetch.get("/api/search", params={"q": query, "page": "1"})
POST with JSON body
from prefab_ui.rx import Rx

name, email = Rx("name"), Rx("email")
Fetch.post("/api/users", body={"name": name, "email": email})
DELETE
from prefab_ui.rx import Rx

user_id = Rx("user_id")
Fetch.delete(f"/api/users/{user_id}")
You can also construct a Fetch directly for full control:
Full form
from prefab_ui.rx import Rx

form_data = Rx("form_data")

Fetch(
    "/api/submit",
    method="POST",
    headers={"X-Custom": "value"},
    body={"data": form_data},
    result_key="response",
)

Error Handling

Non-2xx responses trigger on_error with the status line as $error. This follows the same callback pattern as every other Prefab action.
Error handling
from prefab_ui.actions import Fetch, ShowToast
from prefab_ui.rx import Rx

item = Rx("item")

Fetch.post(
    "/api/save",
    body={"item": item},
    on_success=ShowToast("Saved!", variant="success"),
    on_error=ShowToast("{{ $error }}", variant="error"),
)
A 404 would show a toast reading “404 Not Found”.

Request Bodies

Dict bodies are automatically JSON-serialized with a Content-Type: application/json header. String bodies are sent as-is — useful for form-encoded data or raw text. The auto-set Content-Type won’t override a header you set explicitly.

Combined with Client Actions

Like any action, Fetch composes in a list. A common pattern: show a loading state, make the request, then clear it.
Combined actions
from prefab_ui.components import Button
from prefab_ui.actions import Fetch, SetState
from prefab_ui.rx import Rx

query = Rx("query")

Button(
    "Submit",
    on_click=[
        SetState("loading", True),
        Fetch.post(
            "/api/submit",
            body={"q": query},
            result_key="result",
        ),
        SetState("loading", False),
    ],
)
If the request fails, SetState("loading", False) never runs (the chain short-circuits). Use on_error on the Fetch to handle that case.

API Reference

Fetch Parameters

url
str
required
URL to fetch. Supports {{ key }} interpolation. Can be passed as a positional argument.
method
str
default:"GET"
HTTP method: GET, POST, PUT, PATCH, or DELETE.
headers
dict[str, str]
Request headers. Values support {{ key }} interpolation.
body
dict | str
Request body. Dicts are JSON-serialized automatically. Ignored for GET requests.
result_key
str
State key to store the parsed response under. Supports dot-paths like data.users.

Protocol Reference

Fetch
{
  "action": "fetch",
  "url": "string (required)",
  "method?": "GET | POST | PUT | PATCH | DELETE",
  "headers?": "object",
  "body?": "object | string",
  "resultKey?": "string"
}
For the complete protocol schema, see Fetch.