Skip to content

Instantly share code, notes, and snippets.

@gazpachoking
Last active September 30, 2025 01:41
Show Gist options
  • Select an option

  • Save gazpachoking/d45df5f89e481a2cb675122eb7e9e359 to your computer and use it in GitHub Desktop.

Select an option

Save gazpachoking/d45df5f89e481a2cb675122eb7e9e359 to your computer and use it in GitHub Desktop.
How-to for a long-lived datastar stream that tries to reconnect forever

How to make long-lived connections persist through any interruptions

Intro

Datastar automatically retries sse connections in many cases. It does not not retry in cases that should normally signal the end of a stream. i.e. Error responses from the server or graceful disconnects by the server. We can use the tools that Datastar gives us to retry even in those cases.

Before proceeding: Datastar probably already does what you want. Connections are automatically retried when interrupted, or if the server is not responding. The situations it does not retry are: the server responds with an error (status code >=400,) or if the server gracefully closes the connection. Most of the time you do not want the client to retry in these situations. If you are certain you want the client to keep retrying the connection forever you can use this technique to achieve that.

Goal

Persist an SSE connection from the server through events such as server restarts and temporary error responses. Notify the user if the connection is currently active or not.

Steps

The data-on-interval attribute can be used to repeat. An action on an interval. We can use this to repeatedly keep connecting to the server. The leading modifier can be used to make the first attempt immidiately rather than after the first interval. The caveat is that we need to make sure it does not initiate duplicate connections. The data-indicator attribute will set a signal to true while a connection is trying to connect, or is connected. We can use both of these together to only attempt the reconnection if there is not already one active.

<div data-indicator="_connecting"
     data-on-interval__duration.30s.leading="!$_connecting && @get('/updates')">
</div>

This will attempt to start a new connection within 30 seconds after the previous connection has returned an errored or ended.

To notify the user when the connection is active we need to listen to the datastar-fetch emitted during this connection process. We can create a signal _disconnected and set its value to 'true' when we hear an event that indicates that the stream is not connected, and set it to 'false' when we hear a datastar- event (e.g. datastar-patch-elements) indicating that the connection is up and working. Events can come from any of the SSE connections being initiated on the page, so we also need to check whether the event is coming from a connection initiated on the same element as our intended long-lived connection. The _disconnected signal can then be used in any way we wish to indicate to the user when the stream is disconnected.

<div data-signals-_disconnected="false"
     data-indicator="_connecting"
     data-on-interval__duration.30s.leading="!$_connecting && @get('/updates')"
     data-on-datastar-fetch="el === evt.detail.el &&
                           ((evt.detail.type.startsWith('datastar') && ($_disconnected = false)) ||
                           (['retrying', 'error', 'finished'].includes(evt.detail.type) && ($_disconnected = true)));">
</div>
<div data-show="$_disconnected">Warning: Not connected to server.</div>

This will keep trying to reconnect the SSE and show a div with a warning to the user whenever it is disconnected.

Conclusion

The default Datastar retry semantics are usually best, but when we want to retry even through clear indications that the connection should be over it is possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment