Skip to content

hx-sse:close does not work when there is no data #3920

Description

@aytekinar

I am using/testing HTMX v4.0.0-beta6 right now, and I have the following test file (runnable via uv):

#! /usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.14"
# dependencies = [
#     "sse-starlette~=3.0",
#     "starlette~=1.0",
#     "uvicorn[standard]~=0.51.0",
# ]
# ///
import asyncio
import collections.abc

import sse_starlette
import starlette.applications
import starlette.requests
import starlette.responses
import starlette.routing
import uvicorn

CONTENT = """
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0-beta6/dist/htmx.min.js" defer></script>
    <script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0-beta6/dist/ext/hx-sse.min.js" defer></script>
    <title>HTMX SSE Playground</title>
  </head>
  <body>
    <output aria-live="polite" hx-sse:connect="/sse" hx-sse:close="done"></output>
  </body>
</html>
"""


async def homepage(_: starlette.requests.Request) -> starlette.responses.HTMLResponse:
    return starlette.responses.HTMLResponse(content=CONTENT)


async def sse_endpoint(
    _: starlette.requests.Request,
) -> sse_starlette.EventSourceResponse:
    async def values() -> collections.abc.AsyncIterable[sse_starlette.ServerSentEvent]:
        for idx in range(10):
            yield sse_starlette.ServerSentEvent(data=f"data {idx}")
            await asyncio.sleep(1)

        # if data=None, `hx-sse:close` does not work
        # yield sse_starlette.ServerSentEvent(event="done")
        yield sse_starlette.ServerSentEvent(event="done", data="")

    return sse_starlette.EventSourceResponse(content=values())


app = starlette.applications.Starlette(
    routes=[
        starlette.routing.Route("/sse", sse_endpoint, methods=["GET"]),
        starlette.routing.Route("/", homepage, methods=["GET"]),
    ]
)

if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8080)

Currently, hx-sse:close does not close the long-running hx-sse:connect session when an event done is received with no data. Is this expected behavior? For it to work properly, I need to send an empty string.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions