Hyperscript is primarily designed for front end scripting: local things like toggling a class on a div.
It is designed to pair well with htmx, which uses the hypermedia approach for interacting with servers.
There are times, however, when calling out to a remote server is useful from a scripting context, and hyperscript
supports the fetch command for doing so:
<button _="on click fetch /clickedMessage then
put the result into the next <output/>">
Fetch It
</button>
<output>--</output>
The fetch command uses the fetch API and allows you to configure the fetch as you want, including passing along headers, a body, and so forth.
Notice that the fetch command is (or at least appears) synchronous: you make the call then deal with the results.
in an natural way without await or call backs.
This is hyperscript's async transparency at work!
Pass HTTP method, headers, body, and other options with the with clause. These map to the
second argument of the browser's fetch() API:
fetch /api/users with method:"POST", body:"name=Joe"
fetch /api/me with headers:{Authorization:`Bearer ${token}`} as JSON
Forms can be serialized and posted directly using the as FormData conversion:
fetch /api/submit with method:"POST", body:(<form/> as FormData)
See the fetch command for the full list of options.
By default the response body is returned as a string. You can change this with the as modifier:
| Form | Result |
|---|---|
(no as) |
Response body as a string |
as Text |
Same as the default — response body as a string |
as JSON |
Parse the body as JSON and return the resulting object |
as HTML |
Parse the body as HTML and return a DocumentFragment |
as Response |
Return the raw Response object; you handle body parsing and errors yourself |
as <Conversion> |
Apply any registered conversion to the response text (e.g. as Int, as Fragment) |
By default, fetch throws on non-2xx responses (404, 500, etc.), matching the behavior
of most modern HTTP libraries. You can catch the error with a catch block:
on click
fetch /api/users as JSON
set $users to the result
catch e
log "fetch failed:", e
end
The thrown error carries response and status properties.
If you want to pass through non-2xx responses without throwing, add do not throw
(or don't throw):
fetch /api/users as JSON do not throw
-- result contains whatever the server sent, even on 404
The as Response form never throws on status codes — you get the raw Response object:
fetch /api/users as Response
if it's ok
set $users to it as JSON
end
To customize which status codes throw you can set the _hyperscript.config.fetchThrowsOn property to an
array of regex patterns tested against the stringified status code. The default is
[/4.*/, /5.*/] (all 4xx and 5xx). Set it to [] to disable throwing entirely.
The EventSource extension connects to a Server-Sent Events endpoint and lets you handle server-pushed messages declaratively:
<script type="text/hyperscript">
eventsource ChatStream from /events
on message put it into #messages
end
</script>
This is an extension that ships with hyperscript and needs to be included separately.
The Socket extension provides WebSocket support for real-time, bidirectional communication:
<script type="text/hyperscript">
socket ChatSocket ws://localhost:8080
on message put it into #chat
end
</script>
You can send messages to the socket too:
send "hello" to ChatSocket
Like EventSource, this is a separate extension that ships with hyperscript.
The Intercept extension lets you declare caching strategies for your app without writing service worker boilerplate. Under the hood it registers a service worker that handles caching, offline support, and request interception according to your rules:
<script type="text/hyperscript">
intercept /
precache /, /style.css, /app.js as "v1"
on /api/* use network-first
on *.css, *.js use cache-first
on * use stale-while-revalidate
offline fallback /offline.html
end
</script>
The intercept scope controls which URLs the service worker handles (intercept / covers
the whole site). Each on <pattern> use <strategy> rule matches request paths against a glob
pattern and applies a caching strategy:
Only GET requests are cached. This is a separate extension that ships with hyperscript.