agentleFS
kjnezkjnez/claude-code-django/.claude/skills/htmx-patterns/SKILL.md

htmx-patterns

Skill177 starsChanged 10 months agoMITView on GitHub

HTMX patterns for Django including partial templates, hx-* attributes, and dynamic UI without JavaScript. Use when building interactive UI, handling AJAX requests, or creating dynamic components.

We split this skill into the rules it gives an agent

17 rules. About 0 are common, 10 are distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈10

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use hx-indicator to show loading states during requests

    line 20
  2. Distinctive:

    Use Django messages framework for success/error feedback

    line 25
  3. Distinctive:

    Don't swallow exceptions - log and show user-friendly messages

    line 32
  4. Very specific:

    Check request.headers.get("HX-Request") to detect HTMX requests

    line 37
  5. Very specific:

    Check request.method == "POST" before processing form data

    line 47
  6. Distinctive:

    All HTMX requests automatically include the CSRF token

    line 52
  7. Distinctive:

    Avoid partials that are too large or do too much

    line 68
  8. Very specific:

    Check the HX-Request header to detect HTMX requests:

    line 75
  9. Distinctive:

    Always handle both HTMX and non-HTMX cases

    line 93
  10. Distinctive:

    Use case: Update other parts of page after action

    line 120
  11. Distinctive:

    Use case: Redirect after successful action

    line 126
  12. Distinctive:

    Use case: Different targets for success vs error

    line 131
  13. Distinctive:

    Use case: Major state change that affects whole page

    line 137
  14. Very specific:

    Missing loading indicators: Always use hx-indicator - users click multiple times without feedback

    line 142
  15. Distinctive:

    Not handling form errors: Always return the form with errors on validation failure, not just the success case

    line 144
  16. Very specific:

    Not disabling buttons: Use hx-disabled-elt="this" to prevent duplicate submissions

    line 145
  17. Very specific:

    django-extensions: Use show_urls to verify HTMX endpoints

    line 152

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

HTMX Patterns for Django

Core Philosophy

  • Server renders HTML, not JSON - HTMX requests return HTML fragments, not data
  • Partial templates for dynamic updates - separate _partial.html files for HTMX responses
  • Progressive enhancement - pages work without JavaScript, HTMX enhances UX
  • Minimal client-side complexity - let the server do the heavy lifting

Critical Hints & Reminders

UX Best Practices

Always include loading indicators

  • Use hx-indicator to show loading states during requests
  • Users should never wonder if their action worked
  • Example: <button hx-get="/data/" hx-indicator="#spinner">Load</button>

Always provide user feedback

  • Use Django messages framework for success/error feedback
  • Return error messages in HTMX responses, not silent failures
  • Show what happened after an action completes

Handle errors gracefully

  • Return proper HTTP status codes (400 for validation errors, 500 for server errors)
  • Render form errors in partial templates
  • Don't swallow exceptions - log and show user-friendly messages

Django-Specific Patterns

Always detect HTMX requests

  • Check request.headers.get("HX-Request") to detect HTMX requests
  • Return partial templates for HTMX, full page templates otherwise
  • Pattern: if request.headers.get("HX-Request"): return render(request, "_partial.html", context)

Always return partials for HTMX

  • HTMX requests should return _partial.html templates, not full pages with base.html
  • Full page responses to HTMX requests break the UX and send duplicate HTML
  • Partials should be self-contained HTML fragments

Always validate request.method

  • Check request.method == "POST" before processing form data
  • Return proper status codes (405 Method Not Allowed for wrong methods)

CSRF is already configured globally

  • The base template has hx-headers on <body> - no need to add CSRF tokens to individual forms
  • All HTMX requests automatically include the CSRF token

Template Organization

Naming convention

  • Partials: _partial.html (underscore prefix)
  • Full pages: page.html (no prefix)
  • Example: posts/list.html (full page) includes posts/_list.html (partial)

Structure

  • Full page template extends base.html and includes partial
  • Partial contains only the dynamic HTML fragment
  • HTMX targets the partial's container div

Keep partials focused

  • Each partial should represent one logical UI component
  • Avoid partials that are too large or do too much
  • Compose larger UIs from multiple smaller partials

Django View Patterns

HTMX Detection

Check the HX-Request header to detect HTMX requests:

def my_view(request):
    context = {...}

    if request.headers.get("HX-Request"):
        return render(request, "app/_partial.html", context)

    return render(request, "app/full_page.html", context)

Form Handling Pattern

Key points:

  • Validate form normally
  • On success: return partial with new data OR trigger client-side event
  • On error: return partial with form errors
  • Always handle both HTMX and non-HTMX cases
def create_view(request):
    if request.method == "POST":
        form = MyForm(request.POST)
        if form.is_valid():
            obj = form.save()
            if request.headers.get("HX-Request"):
                return render(request, "app/_item.html", {"item": obj})
            return redirect("app:list")

        # Return form with errors
        if request.headers.get("HX-Request"):
            return render(request, "app/_form.html", {"form": form})
    else:
        form = MyForm()

    return render(request, "app/create.html", {"form": form})

Response Headers Reference

HTMX respects special response headers for client-side behavior:

HX-Trigger

Trigger client-side events after response

  • Use case: Update other parts of page after action
  • Example: response["HX-Trigger"] = "itemCreated"
  • Template listens: <div hx-get="/count/" hx-trigger="itemCreated from:body">

HX-Redirect

Client-side redirect

  • Use case: Redirect after successful action
  • Example: response["HX-Redirect"] = reverse("app:detail", args=[obj.pk])

HX-Retarget / HX-Reswap

Override hx-target and hx-swap from server

  • Use case: Different targets for success vs error
  • Success: response["HX-Retarget"] = "#main"
  • Error: Return partial without changing target (targets the form)

HX-Refresh

Force full page refresh

  • Use case: Major state change that affects whole page
  • Example: response["HX-Refresh"] = "true"

Common Pitfalls

  • Missing loading indicators: Always use hx-indicator - users click multiple times without feedback
  • Full pages in HTMX responses: Return _partial.html, not full pages with base.html - check HX-Request header
  • Not handling form errors: Always return the form with errors on validation failure, not just the success case
  • Not disabling buttons: Use hx-disabled-elt="this" to prevent duplicate submissions
  • N+1 queries: HTMX views need select_related()/prefetch_related() just like regular views

Integration with Other Skills

  • django-templates: Partial template organization and inheritance patterns
  • django-forms: HTMX form submission and validation
  • django-extensions: Use show_urls to verify HTMX endpoints
  • pytest-django-patterns: Testing HTMX endpoints and headers
  • systematic-debugging: Debug HTMX request/response issues

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.