# HTMX Architecture ## Overview General Bots Suite uses **HTMX** for its user interface - a modern approach that delivers the interactivity of a single-page application without the complexity of JavaScript frameworks like React, Vue, or Angular. > **Why HTMX?** > - Simpler code, easier maintenance > - Server-rendered HTML (fast, SEO-friendly) > - Progressive enhancement > - No build step required > - Smaller payload than SPA frameworks --- ## How HTMX Works ### Traditional Web vs HTMX **Traditional (Full Page Reload):** ``` User clicks → Browser requests full page → Server returns entire HTML → Browser replaces everything ``` **HTMX (Partial Update):** ``` User clicks → HTMX requests fragment → Server returns HTML snippet → HTMX updates only that part ``` ### Core Concept HTMX extends HTML with attributes that define: 1. **What triggers the request** (`hx-trigger`) 2. **Where to send it** (`hx-get`, `hx-post`) 3. **What to update** (`hx-target`) 4. **How to update it** (`hx-swap`) --- ## HTMX Attributes Reference ### Request Attributes | Attribute | Purpose | Example | |-----------|---------|---------| | `hx-get` | GET request to URL | `hx-get="/api/tasks"` | | `hx-post` | POST request | `hx-post="/api/tasks"` | | `hx-put` | PUT request | `hx-put="/api/tasks/1"` | | `hx-patch` | PATCH request | `hx-patch="/api/tasks/1"` | | `hx-delete` | DELETE request | `hx-delete="/api/tasks/1"` | ### Trigger Attributes | Attribute | Purpose | Example | |-----------|---------|---------| | `hx-trigger` | Event that triggers request | `hx-trigger="click"` | | | Load on page | `hx-trigger="load"` | | | Periodic polling | `hx-trigger="every 5s"` | | | Keyboard event | `hx-trigger="keyup changed delay:300ms"` | ### Target & Swap Attributes | Attribute | Purpose | Example | |-----------|---------|---------| | `hx-target` | Element to update | `hx-target="#results"` | | `hx-swap` | How to insert content | `hx-swap="innerHTML"` | | | | `hx-swap="outerHTML"` | | | | `hx-swap="beforeend"` | | | | `hx-swap="afterbegin"` | --- ## Suite Architecture ### File Structure ``` ui/suite/ ├── index.html # Main entry point with navigation ├── base.html # Base template ├── home.html # Home page ├── default.gbui # Full desktop layout ├── single.gbui # Simple chat layout ├── designer.html # Visual dialog designer ├── editor.html # Code editor ├── settings.html # User settings ├── css/ │ ├── app.css # Application styles │ ├── apps-extended.css # Extended app styles │ ├── components.css # UI components │ └── global.css # Global styles ├── js/ │ ├── htmx-app.js # HTMX application logic │ ├── theme-manager.js # Theme switching │ └── vendor/ # Third-party libraries ├── partials/ # Reusable HTML fragments ├── auth/ # Authentication views ├── attendant/ # Attendant interface ├── chat/ │ ├── chat.html # Chat component │ ├── chat.css # Chat styles │ └── projector.html # Projector view ├── drive/ # File manager ├── tasks/ # Task manager ├── mail/ # Email client ├── calendar/ # Calendar view ├── meet/ # Video meetings ├── paper/ # Document editor ├── research/ # AI search ├── analytics/ # Dashboards ├── sources/ # Prompts & templates ├── tools/ # Developer tools └── monitoring/ # System monitoring ``` ### Loading Pattern The Suite uses **lazy loading** - components load only when needed: ```html Chat ``` When user clicks "Chat": 1. HTMX requests `/ui/suite/chat/chat.html` 2. Server returns the Chat HTML fragment 3. HTMX inserts it into `#main-content` 4. Only Chat code loads, not entire app --- ## Component Patterns ### 1. Load on Page View ```html
Loading tasks...
``` ### 2. Form Submission ```html
``` **Flow:** 1. User types task, clicks Add 2. HTMX POSTs form data to `/api/tasks` 3. Server creates task, returns HTML for new task item 4. HTMX inserts at beginning of `#task-list` 5. Form resets automatically ### 3. Click Actions ```html
Review quarterly report
``` ### 4. Search with Debounce ```html 🔄
``` **Flow:** 1. User types in search box 2. After 300ms of no typing, HTMX sends request 3. Spinner shows during request 4. Results replace `#search-results` content ### 5. Real-time Updates (WebSocket) ```html
``` **Flow:** 1. WebSocket connects on load 2. History loads via HTMX GET 3. New messages sent via WebSocket (`ws-send`) 4. Server pushes updates to all connected clients ### 6. Polling for Updates ```html
``` ### 7. Infinite Scroll ```html
Loading more...
``` --- ## API Response Patterns ### Server Returns HTML Fragments The server doesn't return JSON - it returns ready-to-display HTML: **Request:** ``` GET /api/tasks ``` **Response:** ```html
Review quarterly report
Update documentation
``` ### Swap Strategies | Strategy | Effect | |----------|--------| | `innerHTML` | Replace contents of target | | `outerHTML` | Replace entire target element | | `beforeend` | Append inside target (at end) | | `afterbegin` | Prepend inside target (at start) | | `beforebegin` | Insert before target | | `afterend` | Insert after target | | `delete` | Delete target element | | `none` | Don't swap (for side effects) | --- ## CSS Integration ### Loading Indicators ```css /* Hidden by default */ .htmx-indicator { display: none; } /* Shown during request */ .htmx-request .htmx-indicator { display: inline-block; } /* Or when indicator IS the requesting element */ .htmx-request.htmx-indicator { display: inline-block; } ``` ### Transition Effects ```css /* Fade in new content */ .htmx-settling { opacity: 0; } .htmx-swapping { opacity: 0; transition: opacity 0.2s ease-out; } ``` --- ## JavaScript Integration ### HTMX Events ```javascript // After any HTMX swap document.body.addEventListener('htmx:afterSwap', (e) => { console.log('Content updated:', e.detail.target); }); // Before request document.body.addEventListener('htmx:beforeRequest', (e) => { console.log('Sending request to:', e.detail.pathInfo.path); }); // After request completes document.body.addEventListener('htmx:afterRequest', (e) => { if (e.detail.successful) { console.log('Request succeeded'); } else { console.error('Request failed'); } }); // On WebSocket message document.body.addEventListener('htmx:wsAfterMessage', (e) => { console.log('Received:', e.detail.message); }); ``` ### Triggering HTMX from JavaScript ```javascript // Trigger an HTMX request programmatically htmx.trigger('#task-list', 'load'); // Make an AJAX request htmx.ajax('GET', '/api/tasks', { target: '#task-list', swap: 'innerHTML' }); // Process new HTMX content htmx.process(document.getElementById('new-content')); ``` --- ## Designer Page Architecture The visual dialog designer uses a hybrid approach: ### Canvas Management (JavaScript) ```javascript // State managed in JavaScript const state = { nodes: new Map(), // Node data connections: [], // Connections between nodes zoom: 1, // Canvas zoom level pan: { x: 0, y: 0 } // Canvas position }; ``` ### File Operations (HTMX) ```html ``` ### Drag-and-Drop (JavaScript) ```javascript // Toolbox items are draggable toolboxItems.forEach(item => { item.addEventListener('dragstart', (e) => { e.dataTransfer.setData('nodeType', item.dataset.nodeType); }); }); // Canvas handles drop canvas.addEventListener('drop', (e) => { const nodeType = e.dataTransfer.getData('nodeType'); createNode(nodeType, e.clientX, e.clientY); }); ``` --- ## Performance Considerations ### 1. Minimize Request Size Return only what's needed: ```html ... ...
``` ### 2. Use Appropriate Triggers ```html hx-trigger="every 30s" hx-trigger="every 1s" hx-trigger="keyup changed delay:300ms" hx-trigger="keyup" ``` ### 3. Lazy Load Heavy Content ```html
``` ### 4. Use `hx-boost` for Navigation ```html ``` --- ## Security ### CSRF Protection HTMX automatically includes CSRF tokens: ```html ``` ```javascript // Configure HTMX to send CSRF token document.body.addEventListener('htmx:configRequest', (e) => { e.detail.headers['X-CSRF-Token'] = document.querySelector('meta[name="csrf-token"]').content; }); ``` ### Content Security - Server validates all inputs - HTML is sanitized before rendering - Authentication checked on every request --- ## Comparison: HTMX vs React | Aspect | HTMX | React | |--------|------|-------| | **Learning Curve** | Low (HTML attributes) | High (JSX, hooks, state) | | **Bundle Size** | ~14KB | ~40KB + app code | | **Build Step** | None | Required | | **Server Load** | More (renders HTML) | Less (returns JSON) | | **Client Load** | Less | More | | **SEO** | Excellent | Requires SSR | | **Complexity** | Simple | Complex | | **Best For** | Content sites, dashboards | Complex SPAs, offline apps | --- ## Further Reading - [HTMX Official Documentation](https://htmx.org/docs/) - [HTMX Examples](https://htmx.org/examples/) - [Hypermedia Systems (Book)](https://hypermedia.systems/) - [Chapter 04: UI Reference](./README.md)