Before: every HTMX response returned the full results_inner template (~400 lines of corrections, meta, pagination, back-to-top) even though only the result list (#urls) changed between searches. After: - Corrections and results-meta use hx-swap-oob="true" — they update in-place in the DOM without duplication, no extra payload - #urls div carries hx-select="#urls" hx-target="#urls" hx-swap="innerHTML" — only the result rows are extracted from the response and swapped - Pagination forms replaced with paginate-btn buttons — JS calls htmx.ajax() directly with select:#urls so only result rows reload - Header search form gains hx-get/hx-target/hx-select for partial updates on subsequent searches Payload reduction per HTMX swap: ~60-70% (no more nav, meta, pagination, back-to-top, htmx-indicator in the swap response body)
38 lines
1.9 KiB
HTML
38 lines
1.9 KiB
HTML
{{define "title"}}{{if .Query}}{{.Query}} — {{end}}{{end}}
|
|
{{define "content"}}
|
|
<div class="results-container">
|
|
<div class="results-header">
|
|
<a href="/" class="results-logo">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
<circle cx="11" cy="11" r="8"/>
|
|
<path d="m21 21-4.35-4.35"/>
|
|
</svg>
|
|
<span>samsa</span>
|
|
</a>
|
|
|
|
<form class="header-search" method="GET" action="/search" role="search" hx-get="/search" hx-target="#urls" hx-swap="innerHTML" hx-select="#urls">
|
|
<div class="search-box">
|
|
<input type="text" name="q" value="{{.Query}}" placeholder="Search…" autocomplete="off">
|
|
<button type="submit" class="search-btn" aria-label="Search">
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="11" cy="11" r="8"/>
|
|
<path d="m21 21-4.35-4.35"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="category-tabs" role="tablist">
|
|
<a href="/search?q={{.Query | urlquery}}&category=" class="category-tab {{if eq .ActiveCategory ""}}active{{end}}">All</a>
|
|
<a href="/search?q={{.Query | urlquery}}&category=general" class="category-tab {{if eq .ActiveCategory "general"}}active{{end}}">General</a>
|
|
<a href="/search?q={{.Query | urlquery}}&category=it" class="category-tab {{if eq .ActiveCategory "it"}}active{{end}}">IT</a>
|
|
<a href="/search?q={{.Query | urlquery}}&category=news" class="category-tab {{if eq .ActiveCategory "news"}}active{{end}}">News</a>
|
|
<a href="/search?q={{.Query | urlquery}}&category=images" class="category-tab {{if eq .ActiveCategory "images"}}active{{end}}">Images</a>
|
|
</div>
|
|
|
|
<div class="results-content">
|
|
{{template "results_inner" .}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|