{"id":16918761,"url":"https://github.com/renerick/htmx-signalr","last_synced_at":"2025-08-03T11:11:48.227Z","repository":{"id":93462478,"uuid":"511628033","full_name":"Renerick/htmx-signalr","owner":"Renerick","description":"htmx extension for interacting with ASP.NET Core SignalR connections directly from HTML","archived":false,"fork":false,"pushed_at":"2024-07-21T20:11:04.000Z","size":96,"stargazers_count":51,"open_issues_count":5,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-27T19:57:43.888Z","etag":null,"topics":["asp-net-core","csharp","dotnet","htmx","signalr"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Renerick.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-07T18:04:27.000Z","updated_at":"2025-01-26T21:54:11.000Z","dependencies_parsed_at":"2024-01-15T17:11:42.828Z","dependency_job_id":"2a50ce81-d28f-4a63-84f0-00d63ceffea7","html_url":"https://github.com/Renerick/htmx-signalr","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Renerick%2Fhtmx-signalr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Renerick%2Fhtmx-signalr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Renerick%2Fhtmx-signalr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Renerick%2Fhtmx-signalr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Renerick","download_url":"https://codeload.github.com/Renerick/htmx-signalr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243852429,"owners_count":20358267,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asp-net-core","csharp","dotnet","htmx","signalr"],"created_at":"2024-10-13T19:41:31.099Z","updated_at":"2025-03-17T07:31:22.262Z","avatar_url":"https://github.com/Renerick.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# htmx-signalr\n\n\u003e [!TIP]\n\u003e If you are using htmx 1.0, switch to `htmx-1.0` branch for legacy version\n\n\u003e [!WARNING]\n\u003e htmx 1.0 implementation of the extension relies on features available in htmx\u003e=v1.8.0 and WILL BREAK on older versions.\n\nThe SignalR extension allows to connect and interact with SignalR server directly from html.\nIt establishes connection to the hub, subscribes to the events, allows to send messages to the server,\nprocesses incoming messages and swaps the content into your htmx page. In a way, it combines features from SSE\nand WebSockets extensions, allowing for bi-directional browser-server communication and supporting\n\"channels\" (\"methods\" in SignalR terminology) to distinguish messages between each other.\n\n[SignalR](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction?view=aspnetcore-6.0) is an open-source\nlibrary that simplifies adding real-time web functionality to apps. Real-time web functionality enables server-side code\nto push content to clients instantly.\n\n## How to use\n\nInstall the extension by including the script into your page, as well as SignalR library itself.\n\n```html\n\n\u003cscript src=\"https://unpkg.com/@microsoft/signalr@next/dist/browser/signalr.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"/js/hx-signalr.js\"\u003e\u003c/script\u003e\n```\n\nActivate the extension by adding `hx-ext` attribute to your page\n\n```html\n\n\u003cdiv hx-ext=\"signalr\"\u003e...\u003c/div\u003e\n```\n\nThe extension provides three attributes to create and interact with the connection.\n\n### `signalr-connect`\n\n`signalr-connect` attribute is used to establish connection to SignalR hub. Pass hub URL as a value attribute in any\nformat, supported by SignalR.\n\n```html\n\n\u003cdiv signalr-connect=\"/hub\"\u003e\u003c/div\u003e\n```\n\nOther attributes will use the connection from the first parent in page structure.\n\n### `signalr-send`\n\n`signalr-send` attribute is used to send messages via SignalR connection. The data is serialized in an object, where\nfields are mapped from input elements\nand values from `hx-include`, `hx-vals`, etc. Additionally, [request headers](https://htmx.org/docs/#request-headers)\nare attached in `HEADERS` property.\n\n```html\n\n\u003cform signalr-send=\"echo\"\u003e\n    \u003cinput type=\"text\" name=\"message\"\u003e\n    \u003cbutton type=\"submit\"\u003eSubmit\u003c/button\u003e\n\u003c/form\u003e\n```\n\nThe form above will be sent as\n\n```json\n{\n  \"message\": \"\u003cvalue\u003e\",\n  \"HEADERS\": {\n    ...\n  }\n}\n```\n\nThat message can be handled by the following hub method\n\n```csharp\npublic async Task Echo(EchoRequest request)\n{\n  await Clients.Caller.SendAsync(\"echo\", $@\"\u003cdiv id=\"\"echo\"\"\u003e{request.message}\u003c/div\u003e\u003cdiv hx-swap-oob=\"\"true\"\" id=\"\"echo-oob-data\"\"\u003e{new Random().Next()}\u003c/div\u003e\");\n}\n\npublic record EchoRequest(string message);\n```\n\n:exclamation::exclamation: Please note, that your request object **MUST** define its fields as strings. The reason for this is the fact that HTML inputs\nhave no distinction between numbers and strings values, but JSON has. Doing client-side conversion will inevitably cause many\nedge-cases and bugs. Server-side validation and mapping is much easier, although it does introduce a bit of a boilerplate.\n\n### `signalr-subscribe`\n\n`signalr-subscribe` attribute is used to declare client method and attach message handler to it. Received messages will\nbe swapped into the page body.\nThe default target is `innerHTML` of the element with that attribute. The target and swapping method can be changed\nwith `hx-target` and `hx-swap` attributes. If the message\ncontains OOB elements, they will also be processed as usual.\n\n```html\n\u003c!-- Standard subscription --\u003e\n\u003cdiv signalr-subscribe=\"counter\"\u003e\n\u003c/div\u003e\n\n\u003c!-- Changing target and swapping method --\u003e\n\u003cdiv signalr-subscribe=\"echo\" hx-target=\"#echo-target\" hx-swap=\"beforeend\"\u003e\n\u003c/div\u003e\n\u003cdiv id=\"echo-target\"\u003e\u003c/div\u003e\n\u003c!-- OOB swapping is supported --\u003e\n\u003cdiv id=\"echo-oob-data\"\u003e\u003c/div\u003e\n```\n\nWhen the message is received, it is processed with similar pipeline as standard htmx responses. That means that\nextensions that transform response content are supported, and you can, for example, use client side templates to render\nJSON data on the page.\n\nAn element can be subscribed to multiple methods by passing their names as comma separated list. But be careful - the\nextension has no native way to specify different swap methods or targets for different methods, so messages for\ndifferent methods can fight over the same target. Best way to use multiple subscriptions is to listen for the\nevents with JS or _hyperscript and handle each method programmatically.\n\n### Events\n\n#### `htmx:signalr:start`\n\nThis event is triggered once connection with the hub has been established. This event is raised on `signalr-connect` element.\n\n- `connectionId` contains id of SignalR connection object (if present)\n\nCancelling the event has no effect.\n\n#### `htmx:signalr:message`\n\nThis event is triggered on the elements with active method subscription when a message is received from the hub\nconnection. `detail` property of the event has a few fields:\n\n- `message` contains message object as received by the handler. Can be modified by event handler, which will affect\n  next processing steps.\n- `method` contains the name of the method, that received the message. Can be used to filter events when using multiple\n  method subscriptions. Modifying this field has no effect.\n- `target` contains target element. Can be changed to redirect swapping to a different target element. Does not affect\n  OOB swaps.\n\nCancelling the event will prevent any further processing.\n\n#### `htmx:signalr:beforeSend`\n\nThis event is triggered just before sending a message. `detail` property contains the parameters of the message being sent, which can be modified by the event handler:\n\n- `method` contains the name of the method being called. Modifying this field will retarget the message to a different handler.\n- `headers` contains the headers, that will be attached into `HEADERS` field.\n- `allParameters` contains all parameters from the form inputs and `hx-vals` attributes.\n- `filteredParameters` contains all parameters after filtering is applied. The value from this field will be sent as-is.\n\nCancelling the event will prevent sending.\n\n#### `htmx:signalr:afterSend`\n\nThis event is triggered just after message was sent. Modifying the data in `details` property has no effect.\n\n- `method` contains the name of the method that was called.\n- `message` contains the data that was sent to the hub.\n\nCancelling this event has no effect.\n\n#### `htmx:signalr:reconnecting`, `htmx:signalr:close`\n\nThese events are matching with corresponding SignalR events\n[`onreconnecting`](https://learn.microsoft.com/en-us/javascript/api/%40microsoft/signalr/hubconnection?view=signalr-js-latest#@microsoft-signalr-hubconnection-onreconnecting),\nand [`onclose`](https://learn.microsoft.com/en-us/javascript/api/%40microsoft/signalr/hubconnection?view=signalr-js-latest#@microsoft-signalr-hubconnection-onclose).\n\n- `error` contains original SignalR error object (if present)\n\n#### `htmx:signalr:reconnected`\n\nThese events are matching with corresponding SignalR event\n[`onreconnected`](https://learn.microsoft.com/en-us/javascript/api/%40microsoft/signalr/hubconnection?view=signalr-js-latest#@microsoft-signalr-hubconnection-onreconnected)\n\n- `connectionId` contains id of SignalR connection object (if present)\n\nYou can use those events to display connection status in the UI and/or gracefully handle connection loss.\nHere is basic example of showing reconnection status using [`hx-on`](https://htmx.org/attributes/hx-on/) attribute\n\n```html\n\u003cdiv id=\"signalr-indicator\" style=\"display: none;\"\u003eConnecting to the hub...\u003c/div\u003e\n\u003cdiv hx-ext=\"signalr\" signalr-connect=\"/hub\"\n     hx-on:htmx:signalr:reconnecting=\"htmx.find('#signalr-indicator').style.display='block'\"\n     hx-on:htmx:signalr:reconnected=\"htmx.find('#signalr-indicator').style.display='none'\"\u003e\u003c/div\u003e\n```\n\n### `htmx.createHubConnection`\n\nSimilar to WebSocket extension, it is possible to provide custom factory method for hub connection. This way you can\ncontrol all aspects of the connection yourself.\n\n```js\nhtmx.createHubConnection = function (url) {\n  return new signalR.HubConnectionBuilder()\n    .withUrl(url)\n    .withAutomaticReconnect(Array(100).fill(5000))   // attempt up to 100 reconnections every 5 seconds\n    .build()\n}\n```\n\n## License\n\nThis library is licensed under the terms of [MIT License](LICENSE)\n\nThe implementation is based on the official [SSE](https://github.com/bigskysoftware/htmx/blob/master/src/ext/sse.js)\nand [WebSockets](https://github.com/bigskysoftware/htmx/blob/master/src/ext/ws.js)\nextensions from [htmx](https://github.com/bigskysoftware/htmx) by Big Sky Software, which are licensed under the terms\nof [BSD Zero-Clause License](https://github.com/bigskysoftware/htmx/blob/master/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenerick%2Fhtmx-signalr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenerick%2Fhtmx-signalr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenerick%2Fhtmx-signalr/lists"}