---
name: templui
description: |
WHEN: User is building Go/Templ web apps, using templUI components, converting sites to Templ,
asking about templ syntax, Script() templates, HTMX/Alpine integration, JavaScript in templ,
or working with .templ files. Also trigger when user mentions "component library", "UI components",
"buttons/cards/modals/tables" in a Go web project, "templ generate", Alpine.js with Go,
or asks how to build interactive UIs in Go without React/Vue. Activate whenever .templ files
are present in the project or templUI is in dependencies.
WHEN NOT: Non-Go projects, pure JavaScript/TypeScript frontend frameworks
---
# templUI & HTMX/Alpine Best Practices
Apply templUI patterns and HTMX/Alpine.js best practices when building Go/Templ web applications.
## The Frontend Stack
The Go/Templ stack uses three complementary tools for interactivity:
| Tool | Purpose | Use For |
|------|---------|---------|
| **HTMX** | Server-driven interactions | AJAX requests, form submissions, partial page updates, live search |
| **Alpine.js** | Client-side state & reactivity | Toggles, animations, client-side filtering, transitions, local state |
| **templUI** | Pre-built UI components | Dropdowns, dialogs, tabs, sidebars (uses vanilla JS via Script() templates) |
**Note:** templUI components use vanilla JavaScript (not Alpine.js) via Script() templates. This is fine - Alpine.js is still part of the stack for your custom client-side needs.
---
## HTMX + Alpine.js Integration
HTMX and Alpine.js work great together. Use HTMX for server communication, Alpine for client-side enhancements.
### When to Use Each
```html
Content
```
### Key Integration Patterns
**Alpine-Morph Extension**: Preserves Alpine state across HTMX swaps:
```html
...
```
**htmx.process() for Alpine Conditionals**: When Alpine's `x-if` renders HTMX content:
```html
```
**Triggering HTMX from Alpine**:
```html
```
---
## templUI Components (Vanilla JS)
templUI components handle their own interactivity via Script() templates using vanilla JavaScript and Floating UI for positioning.
---
## CRITICAL: Templ Interpolation in JavaScript
**Go expressions `{ value }` do NOT interpolate inside `
```
Outside strings (bare expressions), values are JSON-encoded:
```templ
```
### Pattern 4: templ.JSONString for Complex Data
Pass complex structs/maps to JavaScript via attributes:
```templ
```
Or use `templ.JSONScript`:
```templ
@templ.JSONScript("config-data", config)
```
### Pattern 5: templ.OnceHandle for Reusable Scripts
Ensures scripts are only rendered once, even when component is used multiple times:
```templ
var publishHandle = templ.NewOnceHandle()
templ QuoteRow(quote Quote) {
@publishHandle.Once() {
}
}
```
### When to Use Each Pattern
| Scenario | Use |
|----------|-----|
| Simple onclick with one value | Data attribute or `templ.JSFuncCall` |
| Multiple values needed in JS | Data attributes |
| Need event object | `templ.JSFuncCall` with `templ.JSExpression("event")` |
| Inline script with Go values | `{{ value }}` double braces |
| Complex object/struct | `templ.JSONString` or `templ.JSONScript` |
| Reusable script in loop | `templ.OnceHandle` |
### Common Mistakes
```templ
// WRONG - won't interpolate, becomes literal text
onclick="doThing({ id })"
// WRONG - single braces don't work in scripts
// WRONG - Go expression in URL string inside script
// CORRECT alternatives:
onclick={ templ.JSFuncCall("doThing", id) }