CsharpTags.Htmx
1.1.0-beta-4
dotnet add package CsharpTags.Htmx --version 1.1.0-beta-4
NuGet\Install-Package CsharpTags.Htmx -Version 1.1.0-beta-4
<PackageReference Include="CsharpTags.Htmx" Version="1.1.0-beta-4" />
<PackageVersion Include="CsharpTags.Htmx" Version="1.1.0-beta-4" />
<PackageReference Include="CsharpTags.Htmx" />
paket add CsharpTags.Htmx --version 1.1.0-beta-4
#r "nuget: CsharpTags.Htmx, 1.1.0-beta-4"
#:package CsharpTags.Htmx@1.1.0-beta-4
#addin nuget:?package=CsharpTags.Htmx&version=1.1.0-beta-4&prerelease
#tool nuget:?package=CsharpTags.Htmx&version=1.1.0-beta-4&prerelease
CsharpTags.Htmx
A type-safe HTMX attribute library for C# that provides strongly-typed HTML attributes for HTMX functionality.
Overview
This library offers a type-safe way to work with HTMX attributes in C#, providing compile-time safety and IntelliSense support for all HTMX attributes and swap strategies. It's built on top of CsharpTags.Core and follows functional programming principles.
Installation
<PackageReference Include="CsharpTags.Htmx" Version="1.0.0-beta-4" />
Quick Start
using static CsharpTags.Core.Types.Prelude;
using static CsharpTags.Htmx.Types.Prelude;
// Create an element with HTMX attributes
var button = Button.New(
HxPost << "/api/update",
HxTarget << "#result",
HxSwap << SwapStrategy.InnerHTML,
"Update Content"
);
// Use with target helpers
var form = Form.New(
HxPost << "/submit",
HxTargetClosest("tr"),
HxSwap << SwapStrategy.OuterHTML,
// ... form content
);
Core Attributes
HTTP Methods
All standard HTTP methods are supported:
HxGet- GET requestsHxPost- POST requestsHxPut- PUT requestsHxPatch- PATCH requestsHxDelete- DELETE requests
// GET request
var search = Input.New(
TypeAttr << InputType.Text,
HxGet << "/api/search",
HxTarget << "#results"
);
// POST request
var form = Form.New(
HxPost << "/api/submit",
HxTarget << "#response",
// ... form fields
);
Target Selection
HTMX provides flexible target selection:
// Target specific element by ID
HxTarget << "#results"
// Target the current element
HxTargetThis
// Target closest ancestor matching selector
HxTargetClosest("tr")
HxTargetClosest(".container")
// Find first child matching selector
HxTargetFind(".error")
HxTargetFind("input[type='text']")
// Target next sibling
HxTargetNext_
HxTargetNext(".item")
// Target previous sibling
HxTargetPrevious_
HxTargetPrevious(".item")
Swap Strategies
Control how response content is swapped into the DOM:
// Basic strategies
HxSwap << SwapStrategy.InnerHTML; // Replace inner HTML (default)
HxSwap << SwapStrategy.OuterHTML; // Replace entire element
HxSwap << SwapStrategy.BeforeBegin; // Insert before target
HxSwap << SwapStrategy.AfterBegin; // Insert as first child
HxSwap << SwapStrategy.BeforeEnd; // Insert as last child
HxSwap << SwapStrategy.AfterEnd; // Insert after target
HxSwap << SwapStrategy.Delete; // Delete target element
HxSwap << SwapStrategy.None; // Don't swap
HxSwap << SwapStrategy.TextContent; // Replace text only
Swap Modifiers
Add modifiers to swap strategies for advanced behavior:
// Combine swap strategy with modifiers using + operator
HxSwap << SwapStrategy.InnerHTML + "swap:1s"
HxSwap << SwapStrategy.OuterHTML + "transition:true"
HxSwap << SwapStrategy.InnerHTML + "scroll:top"
// Or use Modify method
HxSwap << SwapStrategy.OuterHTML.Modify("focus-scroll:true settle:100ms")
// Multiple modifiers
HxSwap << SwapStrategy.InnerHTML + "swap:500ms transition:true scroll:bottom"
Synchronization Strategies
Control how HTMX synchronizes concurrent requests:
// Build sync strategy with + operator
HxSync << (SyncStrategy.Drop + "#form") // Drop if request in flight
HxSync << (SyncStrategy.Abort + "#form") // Abort on new request
HxSync << (SyncStrategy.Replace + "#form") // Replace current request
HxSync << (SyncStrategy.Queue + "#form") // Add to queue
HxSync << (SyncStrategy.QueueFirst + "#form") // Add to front of queue
HxSync << (SyncStrategy.QueueLast + "#form") // Add to end of queue
HxSync << (SyncStrategy.QueueAll + "#form") // Queue all requests
Triggers
Define when requests are triggered:
// Basic triggers
HxTrigger << "click"
HxTrigger << "change"
HxTrigger << "submit"
HxTrigger << "keyup"
// Advanced triggers with modifiers
HxTrigger << "keyup changed delay:500ms"
HxTrigger << "click once"
HxTrigger << "revealed"
HxTrigger << "intersect once"
// Multiple triggers
HxTrigger << "click, keyup[key=='Enter']"
Event Handling
Handle HTMX events inline:
// Built-in common event handlers
HxOnClick << "alert('Clicked!')"
HxOnSubmit << "validateForm()"
HxOnChange << "updatePreview()"
HxOnKeyUp << "search()"
HxOnLoad << "initialize()"
HxOnMouseOver << "highlight()"
// Custom event handlers
HxOn("custom-event") << "handleCustom()"
// HTMX-specific events
HxOn("htmx:beforeRequest") << "showLoading()"
HxOn("htmx:afterRequest") << "hideLoading()"
HxOn("htmx:responseError") << "showError()"
Form Enhancements
Enhance forms with HTMX attributes:
// Boost links and forms to use AJAX
HxBoost << true
// Validate before submitting
HxValidate << true
// Confirmation dialog
HxConfirm << "Are you sure?"
// Prompt for input
HxPrompt << "Enter value:"
// Include additional values
HxVals << "{\"key\": \"value\"}"
// Select subset of response
HxSelect << "#content"
// Out-of-band swap
HxSwapOob << "true"
Advanced Attributes
// Push URL to browser history
HxPushUrl << "/new-url"
HxPushUrl << "true"
// Specify indicator element
HxIndicator << "#loading"
// Include additional elements in request
HxInclude << "[name='filter']"
// Set request headers
HxHeaders << "{\"X-Custom\": \"value\"}"
// Encoding type
HxEncoding << "multipart/form-data"
// Disable HTMX processing
HxDisabled << true
// History management
HxHistoryElt << true
// Disinherit from parent
HxDisinherit << "hx-trigger"
// Use extensions
HxExt << "json-enc"
Timing and Delays
// Delay before request
HxDelay << 500 // 500ms delay
// Settle time after swap
HxSettle << 100 // 100ms settle
Complete Examples
Search with Debouncing
using static CsharpTags.Core.Types.Prelude;
using static CsharpTags.Htmx.Types.Prelude;
var searchComponent = Div.New(
// Search input with debouncing
Input.New(
TypeAttr << InputType.Text,
Name << "query",
HxGet << "/api/search",
HxTrigger << "keyup changed delay:300ms",
HxTarget << "#search-results",
HxIndicator << "#loading",
Placeholder << "Search users..."
),
// Loading indicator
Div.New(
Id_ << "loading",
Class << "htmx-indicator",
"Searching..."
),
// Results container
Div.New(Id_ << "search-results")
);
Inline Edit Form
var editForm = Form.New(
HxPut << "/api/users/{userId}",
HxTargetClosest("tr"), // Replace the table row
HxSwap << SwapStrategy.OuterHTML + "transition:true",
HxConfirm << "Save changes?",
// Form fields
Input.New(
TypeAttr << InputType.Text,
Name << "username",
Value << currentUsername
),
// Save button
Button.New(
TypeAttr << InputType.Submit,
"Save"
),
// Cancel button (triggers cancel action)
Button.New(
HxGet << $"/api/users/{userId}/display",
HxTargetClosest("tr"),
"Cancel"
)
);
Infinite Scroll
var feed = Div.New(
Id_ << "feed",
// Current items
items.Select(item => Div.New(
Class << "feed-item",
H3.New(item.Title),
P.New(item.Content)
)).ToHtml(),
// Load more trigger
Div.New(
HxGet << $"/api/feed?page={nextPage}",
HxTrigger << "revealed",
HxTarget << "#feed",
HxSwap << SwapStrategy.BeforeEnd,
Class << "loading-indicator",
"Loading more..."
)
);
Tabbed Interface
var tabs = Div.New(
Class << "tabs",
// Tab buttons
Div.New(
Class << "tab-buttons",
Button.New(
HxGet << "/content/tab1",
HxTarget << "#tab-content",
Class << "active",
"Tab 1"
),
Button.New(
HxGet << "/content/tab2",
HxTarget << "#tab-content",
"Tab 2"
),
Button.New(
HxGet << "/content/tab3",
HxTarget << "#tab-content",
"Tab 3"
)
),
// Tab content area
Div.New(
Id_ << "tab-content",
Class << "tab-content",
initialContent
)
);
Modal Dialog
var modal = Div.New(
Id_ << "modal",
Role << "dialog",
AriaModal << "true",
// Close on click outside
HxOn("click") << "if(event.target === this) htmx.remove(this)",
Div.New(
Class << "modal-content",
// Header
Div.New(
Class << "modal-header",
H2.New("Confirm Action"),
Button.New(
HxOnClick << "htmx.remove(#modal)",
Class << "close",
"×"
)
),
// Body
Div.New(
Class << "modal-body",
P.New("Are you sure you want to proceed?")
),
// Footer with actions
Div.New(
Class << "modal-footer",
Button.New(
HxPost << "/api/action",
HxTarget << "#result",
HxSwap << SwapStrategy.OuterHTML,
HxConfirm << "This cannot be undone. Continue?",
Class << "btn-primary",
"Confirm"
),
Button.New(
HxOnClick << "htmx.remove(#modal)",
Class << "btn-secondary",
"Cancel"
)
)
)
);
Error Handling
Handle HTMX errors gracefully:
var formWithErrorHandling = Form.New(
HxPost << "/api/submit",
HxTarget << "#response",
// Success handling
HxOn("htmx:afterRequest") << """
if(event.detail.successful) {
showNotification('Saved successfully!');
}
""",
// Error handling
HxOn("htmx:responseError") << """
showError('Failed to save. Please try again.');
""",
// Form fields
Input.New(TypeAttr << InputType.Text, Name << "data"),
Button.New(TypeAttr << InputType.Submit, "Submit")
);
Requirements
- .NET 8.0 or .NET 10.0
- CsharpTags.Core package
- HTMX library in your frontend (typically via CDN or npm)
Links
License
MIT License - see LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CsharpTags.Core (>= 1.1.0-beta-4)
-
net8.0
- CsharpTags.Core (>= 1.1.0-beta-4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.0-beta-4 | 33 | 3/7/2026 |
| 1.1.0-beta-3 | 56 | 2/15/2026 |
| 1.1.0-beta-2 | 52 | 2/2/2026 |
| 1.1.0-beta-1 | 63 | 1/6/2026 |
| 1.0.0-beta-5 | 411 | 12/10/2025 |
| 1.0.0-beta-4 | 410 | 12/9/2025 |
| 1.0.0-beta-3 | 152 | 11/26/2025 |
| 1.0.0-beta-2 | 167 | 11/25/2025 |