https://github.com/benallfree/pocketbase-htmx-ext-sse
HTMX SSE extension for PocketBase
https://github.com/benallfree/pocketbase-htmx-ext-sse
Last synced: 7 months ago
JSON representation
HTMX SSE extension for PocketBase
- Host: GitHub
- URL: https://github.com/benallfree/pocketbase-htmx-ext-sse
- Owner: benallfree
- Created: 2025-02-11T21:47:27.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-02-11T21:58:04.000Z (8 months ago)
- Last Synced: 2025-03-13T01:47:41.032Z (7 months ago)
- Language: JavaScript
- Homepage: https://htmx-sse.pockethost.io
- Size: 22.5 KB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# HTMX SSE for PocketBase
A custom Server-Sent Events (SSE) extension for HTMX that integrates with PocketBase's realtime API.
## Overview
This extension builds upon the [official HTMX SSE extension](https://htmx.org/extensions/sse/) but is specifically designed to work with [PocketBase's realtime API](https://pocketbase.io/docs/api-realtime/). It automatically handles PocketBase's connection protocol and subscription management.
Demo: https://htmx-sse.pockethost.io/
Demo code: https://github.com/benallfree/pocketpages/tree/main/starters/htmx## Features
- Automatic connection handling with PocketBase's realtime API
- Seamless integration with HTMX's event system
- Automatic subscription to specified topics
- Support for dynamic content updates
- Compatible with existing HTMX SSE event names and triggers## Installation
```bash
npm install pocketbase-htmx-ext-sse
```or
```html
```
## Usage
Add the extension to your HTML and specify the topics to subscribe to:
```html
Send```
### Backend Implementation
#### Using PocketPages
> _See [PocketPages send()](https://pocketpages.dev/docs/context-api/send) for more information._
Create an endpoint at `/api/chat.ejs`:
```html
const { message } = body()
send('chat', `<div>${message}</div>`)
return { result: 'ok' }```
Or using PocketPage's render capture feature for more complex content:
```html
const { message } = body()
send('chat')
```#### Using PocketBase JSVM
Create a custom API endpoint in your PocketBase app:
```javascript
routerAdd('POST', '/api/chat', (c) => {
const data = $apis.requestInfo(c).data
const message = data.message// Get all clients from the subscription broker
const clients = $app.subscriptionsBroker().clients()// Filter clients that are subscribed to the 'chat' topic
Object.entries(clients)
.filter(([_, client]) => client.hasSubscription('chat'))
.forEach(([_, client]) => {
// Send the message to each subscribed client
client.send({
name: 'chat',
data: `${message}`,
})
})return c.json({ result: 'ok' })
})
```This implementation:
1. Gets all connected clients from PocketBase's subscription broker
2. Filters for clients that are subscribed to the 'chat' topic
3. Sends the formatted message directly to each subscribed client
4. Returns a success response### SSE Message Format
When you connect to the realtime endpoint, you'll receive messages in this format:
```
id:NJMhEaQbJ4lJ7L5QIsenCCG8wzdH8mETTp2ncclX
event:PB_CONNECT
data:{"clientId":"NJMhEaQbJ4lJ7L5QIsenCCG8wzdH8mETTp2ncclX"}id:NJMhEaQbJ4lJ7L5QIsenCCG8wzdH8mETTp2ncclX
event:chat
data:asdfid:NJMhEaQbJ4lJ7L5QIsenCCG8wzdH8mETTp2ncclX
event:chat
data:"\n"This is a multiline message
\nThat was JSON encoded
\n
```The extension handles:
1. The initial `PB_CONNECT` event to establish the connection
2. Automatic subscription to your specified topics
3. Swapping the `data` content into your elements based on the matching `event` name> **Note:** The extension will attempt to parse any JSON-parsable strings in the `data` field. This is particularly useful for multiline content, which should be JSON encoded to properly fit within a single line in the SSE data stream. If parsing fails (i.e., the content is not valid JSON), the original string is used.
### Configuration Attributes
- `hx-ext="pocketbase-sse"` - Activates the SSE extension
- `sse-swap="topic"` - Defines which topic(s) to subscribe to (comma-separated for multiple topics)
- `hx-swap="beforeend"` - (Optional) Controls how new content is inserted## How It Works
1. When the extension initializes, it establishes a connection to PocketBase's realtime API
2. Upon successful connection (`PB_CONNECT` event), it automatically subscribes to the specified topics
3. Incoming messages on the subscribed topics trigger content updates according to the configured swap behavior## Events
This extension uses the same event names as the official HTMX SSE extension for compatibility:
- `htmx:sseOpen` - Triggered when the SSE connection is established
- `htmx:sseMessage` - Triggered when a message is received
- `htmx:sseError` - Triggered when an error occurs
- `htmx:sseClose` - Triggered when the connection is closedYou can use these events in your triggers and event handlers just like with the standard SSE extension.
## Example with Multiple Topics
```html
```## Advanced Usage
### Custom Event Handling
You can listen for specific SSE events:
```html
```### Error Handling
The extension automatically handles connection errors and reconnection attempts. You can style disconnected states using the `sse-disconnected` class that's added to the parent element when connection is lost.
```css
.sse-disconnected {
opacity: 0.5;
}
```## License
MIT
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.