I’m using Stimulus and Turbo, and I’m trying to figure out the best way to send custom JavaScript data or events from the server to the frontend, similar to how Phoenix LiveView can use push_event without touching the DOM.
Is there a way to trigger a Stimulus controller action from the server, without actually updating or injecting any DOM (like append, replace, etc.)?
I basically want to notify my frontend with data over Turbo Streams or something similar — but without rendering any HTML. Is that possible? Or do I always have to modify the DOM in some way for it to reach Stimulus?
Would you consider a Cable (web socket) broadcast from the server as a possible solution? That’s the only avenue I can think of for this.
Also, have you investigated how Phoenix manages this?
As far as I know, there’s no way for a server to send a raw native JS event directly to a page open in a browser over normal HTTP transport. Either the script on the page is making a polling request and translating that into an event, or the event is a translation from a user-initiated-request response. But to have that initiated directly from the server, without it being a response to a user request, kind of breaks how HTTP works.
Cable steps around this by setting up a back-channel in the form of a persistent open socket that can be read from or written to on either end, like a UDP port. This has to be established by the script on the page on first load, and then there’s a heartbeat process that checks if it’s still viable.
Know that turbo-stream (on controller request or actioncable) is nothing more than a custom element. With that you can create a custom action that, when gets connected to the dom, can run som JS. See: Turbo Handbook