# HTMX Integration Patterns - Public Web Frontend
**Last Updated:** November 18, 2025
---
## Overview
This document outlines HTMX usage patterns, best practices, and common implementations for the Code of Conquest web frontend.
**HTMX Benefits:**
- Server-side rendering with dynamic interactions
- No JavaScript framework overhead
- Progressive enhancement (works without JS)
- Clean separation of concerns
- Natural integration with Flask/Jinja2
---
## Core HTMX Attributes
### hx-get / hx-post / hx-put / hx-delete
Make HTTP requests from HTML elements:
```html
```
### hx-target
Specify where to insert the response:
```html
```
### hx-swap
Control how content is swapped:
```html
```
### hx-trigger
Specify what triggers the request:
```html
...
...
Status: ...
...
```
---
## Common Patterns
### Form Submission
**Pattern:** Submit form via AJAX, replace form with result
```html
```
**Backend Response:**
```python
@characters_bp.route('/', methods=['POST'])
def create_character():
# Create character via API
response = api_client.post('/characters', request.form)
if response.status_code == 200:
character = response.json()['result']
return render_template('partials/character_card.html', character=character)
else:
return render_template('partials/form_error.html', error=response.json()['error'])
```
### Delete with Confirmation
**Pattern:** Confirm before deleting, remove element on success
```html
{{ character.name }}
```
**Backend Response (empty for delete):**
```python
@characters_bp.route('/', methods=['DELETE'])
def delete_character(character_id):
api_client.delete(f'/characters/{character_id}')
return '', 200 # Empty response removes element
```
### Search/Filter
**Pattern:** Live search with debouncing
```html
Searching...
```
### Tabs
**Pattern:** Tab switching without page reload
```html
```
### Polling for Updates
**Pattern:** Auto-refresh session status
```html
Loading status...
```
**Conditional Polling (stop when complete):**
```html
Status: {{ session.status }}
```
### Infinite Scroll
**Pattern:** Load more as user scrolls
```html
{% for character in characters %}
{% include 'partials/character_card.html' %}
{% endfor %}
{% if has_more %}
Loading more...
{% endif %}
```
---
## Advanced Patterns
### Dependent Dropdowns
**Pattern:** Update second dropdown based on first selection
```html
```
### Out of Band Swaps
**Pattern:** Update multiple areas from single response
```html
HP: 50/100
```
**Backend Response:**
```html
You dealt 15 damage!
HP: 45/100
```
### Optimistic UI
**Pattern:** Show result immediately, revert on error
```html
```
**Immediate feedback with CSS:**
```css
.htmx-request .htmx-indicator {
display: inline;
}
```
### Progressive Enhancement
**Pattern:** Fallback to normal form submission
```html
```
---
## HTMX + Appwrite Realtime
### Hybrid Approach
Use HTMX for user actions, Appwrite Realtime for server push updates:
```html
```
---
## Error Handling
### Show Error Messages
```html
```
**Backend Error Response:**
```python
@characters_bp.route('/', methods=['POST'])
def create_character():
try:
# Create character
pass
except ValidationError as e:
response = make_response(render_template('partials/error.html', error=str(e)), 400)
response.headers['HX-Retarget'] = '#error-container'
return response
```
### Retry on Failure
```html
Loading...
```
---
## Loading Indicators
### Global Indicator
```html
Loading...
```
### Inline Indicator
```html
```
---
## Best Practices
### 1. Use Semantic HTML
```html
Submit
```
### 2. Provide Fallbacks
```html
```
### 3. Use hx-indicator for Loading States
```html
⏳
```
> **IMPORTANT:** The `htmx-indicator` class is **hidden by default** (opacity: 0) and only shown during active requests. Never put this class on a container that should remain visible - only use it on loading spinners/messages that should appear during requests and disappear after.
### 4. Debounce Search Inputs
```html
```
### 5. Use CSRF Protection
```html
```
---
## Debugging
### HTMX Events
Listen to HTMX events for debugging:
```html
```
### HTMX Logger Extension
```html
```
---
## Performance Tips
### 1. Use hx-select to Extract Partial
```html
```
### 2. Disable During Request
```html
```
### 3. Use hx-sync for Sequential Requests
```html
```
---
## Related Documentation
- **[TEMPLATES.md](TEMPLATES.md)** - Template structure and conventions
- **[TESTING.md](TESTING.md)** - Manual testing guide
- **[/api/docs/API_REFERENCE.md](../../api/docs/API_REFERENCE.md)** - API endpoints
- **[HTMX Official Docs](https://htmx.org/docs/)** - Complete HTMX documentation
---
**Document Version:** 1.2
**Created:** November 18, 2025
**Last Updated:** November 26, 2025