Skip to content

Instantly share code, notes, and snippets.

@kubukoz
Last active June 23, 2025 08:09
Show Gist options
  • Save kubukoz/97213a24ff292d12870ef10e0ba0133b to your computer and use it in GitHub Desktop.
Save kubukoz/97213a24ff292d12870ef10e0ba0133b to your computer and use it in GitHub Desktop.
http4s + scalatags + htmx + fs2/SSE
//> using scala 3.7
//> using dep org.http4s::http4s-ember-server:0.23.30
//> using dep org.http4s::http4s-dsl:0.23.30
//> using dep org.http4s::http4s-scalatags::0.25.2
//> using option -Wunused:all
import scalatags.Text.all.*
import cats.effect.*
import fs2.Stream
import org.http4s.*
import org.http4s.dsl.io.*
import org.http4s.ember.server.*
import org.http4s.implicits.*
import org.http4s.scalatags.*
import scala.concurrent.duration.{span as _, *}
object SSEApp extends IOApp.Simple:
val indexPage = html(
meta(charset := "utf-8"),
head(
script(src := "https://unpkg.com/[email protected]"),
script(src := "https://unpkg.com/[email protected]"),
),
body(
h1("http4s/fs2 ❤️ HTMX + SSE"),
div(
id := "random-box",
p(
"Your UUID: ",
span(
attr("hx-ext") := "sse",
attr("sse-connect") := "/events",
attr("sse-swap") := "message",
),
),
),
),
)
val routes = HttpRoutes.of[IO] {
case GET -> Root => Ok(indexPage)
case GET -> Root / "events" =>
Ok(Stream.fixedRateStartImmediately[IO](100.millis).evalMap { _ =>
IO.randomUUID.map { uuid =>
ServerSentEvent(data = Some(uuid.toString))
}
})
}
override def run: IO[Unit] =
EmberServerBuilder
.default[IO]
.withHttpApp(routes.orNotFound)
.build
.evalTap { server =>
IO.println(
s"Server running at ${server.baseUri}"
)
}
.useForever
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment