### Direct Routing Example Source: https://github.com/egil/htmxor/blob/main/docs/index.md Demonstrates how direct routing bypasses the root component and standard layout. It shows how a component can be routed to directly, optionally including a specified HtmxLayout. ```text HTTP GET /my-htmx-page-with-layout HtmxLayout --> MyHtmxPageWithHtmxLayout HTTP GET /my-htmx-page MyHtmxPage ``` -------------------------------- ### Add Htmxor Services and Middleware to Program.cs Source: https://github.com/egil/htmxor/blob/main/docs/index.md Modify Program.cs to include Htmxor services and middleware for Blazor applications. This setup is essential for enabling Htmxor functionality. ```csharp var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services .AddRazorComponents() .AddHtmx(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error", createScopeForErrors: true); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAntiforgery(); app.UseHtmxAntiforgery(); app.MapRazorComponents() .AddHtmxorComponentEndpoints(app); app.Run(); ``` -------------------------------- ### Setup Htmxor Services and Middleware Source: https://context7.com/egil/htmxor/llms.txt Registers Htmxor services and antiforgery middleware. Configure global htmx behavior via HtmxConfig. Registers direct-routing endpoints for Blazor components. ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services .AddRazorComponents() .AddHtmx(config => { config.DefaultSwapStyle = SwapStyle.outerHTML; config.SelfRequestsOnly = true; config.HistoryCacheSize = 20; config.ScrollBehavior = ScrollBehavior.smooth; config.GlobalViewTransitions = true; }); var app = builder.Build(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAntiforgery(); app.UseHtmxAntiforgery(); // Injects antiforgery token into htmx requests app.MapRazorComponents() .AddHtmxorComponentEndpoints(app); // Registers htmx direct-routing endpoints app.Run(); ``` -------------------------------- ### Trigger Fluent Builder Examples Source: https://context7.com/egil/htmxor/llms.txt Construct complex hx-trigger attribute values using the Trigger fluent builder. Supports various events, conditions, delays, throttling, and queuing options. ```razor @* LiveSearch.razor *@ @using static Htmxor.Constants @* hx-trigger="keyup changed delay:500ms" *@ @* hx-trigger="click[ctrlKey] throttle:2s consume queue:last" *@ @* hx-trigger="every 10s" — polling *@
Loading price...
@* hx-trigger="revealed" — lazy load on scroll into view *@ @* hx-trigger="click, load" — fire on click OR on page load *@
Check Notifications
@* hx-trigger="intersect root:.feed threshold:0.25" *@
Load More
@* hx-trigger="sse:newMessage" *@
Messages
``` -------------------------------- ### Handle Standard and Direct Routing Modes in Blazor Source: https://context7.com/egil/htmxor/llms.txt Create Blazor components that respond to both full-page requests (Standard Routing Mode) and htmx fragment requests (Direct Routing Mode) on the same URL. ```razor @* Layout-aware component responding to both routing modes *@ @page "/products" @attribute [HtmxRoute("/products")] @inject HtmxContext Htmx @if (Htmx.Request.RoutingMode == RoutingMode.Standard) { @* Full page — rendered inside App.razor → Routes → MainLayout → Products *@

Product Catalog

} else { @* Direct htmx request — rendered standalone, wrapped only in HtmxorLayout *@ @* Htmx.Request.IsHtmxRequest == true *@ @* Htmx.Request.Target == "product-grid" *@ } @code { [SupplyParameterFromQuery] public string? Q { get; set; } private List AllProducts = ["Widget A", "Widget B", "Gadget X"]; private List FilteredProducts => string.IsNullOrEmpty(Q) ? AllProducts : AllProducts.Where(p => p.Contains(Q, StringComparison.OrdinalIgnoreCase)).ToList(); } ``` -------------------------------- ### Configure Global Htmx Settings Source: https://context7.com/egil/htmxor/llms.txt Configure global htmx behavior by passing an HtmxConfig object to AddHtmx. This controls swap styles, history, scrolling, security, and more. ```csharp builder.Services .AddRazorComponents() .AddHtmx(config => { // Swap behavior config.DefaultSwapStyle = SwapStyle.outerHTML; config.DefaultSwapDelay = TimeSpan.FromMilliseconds(0); config.DefaultSettleDelay = TimeSpan.FromMilliseconds(20); // History config.HistoryEnabled = true; config.HistoryCacheSize = 10; config.RefreshOnHistoryMiss = false; // Scroll config.ScrollBehavior = ScrollBehavior.smooth; config.ScrollIntoViewOnBoost = true; config.DefaultFocusScroll = false; // Security config.SelfRequestsOnly = true; config.AllowEval = false; config.WithCredentials = false; // Performance config.GetCacheBusterParam = true; config.GlobalViewTransitions = true; // CSS class names config.IndicatorClass = "is-loading"; config.RequestClass = "htmx-request"; // Request timeout config.Timeout = TimeSpan.FromSeconds(30); }); ``` -------------------------------- ### SwapStyleBuilder for hx-swap and HX-Reswap Source: https://context7.com/egil/htmxor/llms.txt Construct hx-swap attribute strings or HX-Reswap response headers using the SwapStyleBuilder. Supports delays, scroll control, focus preservation, and transitions. ```razor @* Used directly in markup *@ @* hx-swap="outerHTML swap:200ms settle:100ms show:window:top" *@ @* hx-swap="innerHTML scroll:top ignoreTitle:true transition:true" *@
Load Content
``` ```csharp // Used in HtmxResponse.Reswap() from an event handler private void OnPost(HtmxEventArgs e) { e.Response.Reswap( new SwapStyleBuilder(SwapStyle.beforeend) .AfterSwapDelay(TimeSpan.FromMilliseconds(50)) .ShowOnBottom("#item-list") .PreserveFocus() ); } ``` -------------------------------- ### Htmxor Routing Mode Logic Source: https://github.com/egil/htmxor/blob/main/docs/index.md Illustrates the logic for determining the routing mode in Htmxor based on the presence and values of htmx request headers like HX-Request and HX-Boosted. ```python if ( HX-Request is null || ( HX-Boosted is not null && HX-Target is null ) ) RoutingMode.Standard else RoutingMode.Direct ``` -------------------------------- ### Update _Imports.razor for Htmxor Namespaces and Layout Source: https://github.com/egil/htmxor/blob/main/docs/index.md Update _Imports.razor to include necessary Htmxor namespaces and optionally set a default layout for components using the HtmxLayout attribute. ```csharp @using System.Net.Http @using System.Net.Http.Json @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using static Microsoft.AspNetCore.Components.Web.RenderMode @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using Htmxor.Components @using Htmxor.Http @using Htmxor @using static Htmxor.Constants @* only if adding a custom layout for using during direct requests in step 4 above *@ @attribute [HtmxLayout(typeof(HtmxorLayout))] ``` -------------------------------- ### Create Optional Direct Request Layout Source: https://github.com/egil/htmxor/blob/main/docs/index.md Define an optional layout component for direct routing scenarios in Htmxor. This layout inherits from HtmxLayoutComponentBase and includes the HeadOutlet for dynamic page titles. ```razor @inherits HtmxLayoutComponentBase @Body ``` -------------------------------- ### HtmxAsyncLoad Component Usage Source: https://context7.com/egil/htmxor/llms.txt Use HtmxAsyncLoad to render a placeholder during initial page load and load content asynchronously via HTMX. The ChildContent is rendered on the subsequent Direct request. ```razor @* Dashboard.razor *@ @page "/dashboard"

Dashboard

Loading sales data...
@* This renders only on the async htmx follow-up request *@

Sales Chart

@foreach (var order in Orders) { }
OrderStatus
@order.Id@order.Status
@code { private string SalesData = "[100, 200, 150, 300]"; private List<(int Id, string Status)> Orders = [(1, "Shipped"), (2, "Pending")]; } ``` -------------------------------- ### HtmxLayoutAttribute and HtmxLayoutComponentBase Source: https://context7.com/egil/htmxor/llms.txt Designates a layout component for htmx Direct requests and provides a base class for such layouts. HtmxLayoutComponentBase automatically renders HeadOutlet for PageTitle updates. ```razor @* Components/Layout/HtmxorLayout.razor *@ @inherits HtmxLayoutComponentBase @Body ``` ```razor @* _Imports.razor — applies the htmx layout to all components in this folder *@ @using Htmxor @using Htmxor.Components @using Htmxor.Http @using static Htmxor.Constants @attribute [HtmxLayout(typeof(HtmxorLayout))] ``` ```razor @* Override the layout for a specific component with higher priority *@ @attribute [HtmxLayout(typeof(SpecialHtmxLayout), Priority = 10)] @page "/special"

Special Page

``` -------------------------------- ### Update App.razor for Htmxor Components Source: https://github.com/egil/htmxor/blob/main/docs/index.md Modify App.razor to include Htmxor components and enable hx-boost for enhanced navigation and forms. This integrates Htmxor's client-side features. ```razor ``` -------------------------------- ### Handle Htmx POST and DELETE Events in Blazor Source: https://context7.com/egil/htmxor/llms.txt Implement custom Blazor event handlers for htmx POST and DELETE requests using HtmxEventArgs. This allows access to HtmxRequest and HtmxResponse objects. ```razor @* TodoList.razor *@ @page "/todos" @attribute [HtmxRoute("/todos", Methods = [HttpMethods.Post])] @attribute [HtmxRoute("/todos/{Id:int}", Methods = [HttpMethods.Delete])]
    @foreach (var todo in Todos) {
  • @todo.Text
  • }
@code { private List<(int Id, string Text)> Todos = [(1, "Buy milk"), (2, "Write tests")]; private int nextId = 3; [SupplyParameterFromForm] public string? Text { get; set; } [Parameter] public int Id { get; set; } private void HandleAdd(HtmxEventArgs e) { Todos.Add((nextId++, Text ?? "Untitled")); e.Response.Trigger("todoAdded"); } private void HandleDelete(HtmxEventArgs e) { Todos.RemoveAll(t => t.Id == Id); e.Response.EmptyBody(); // Return 200 with no content — htmx removes the element } } ``` -------------------------------- ### HtmxRouteAttribute for Conditional Routing Source: https://context7.com/egil/htmxor/llms.txt Extends Blazor routing with htmx-aware constraints. A component is accessible only when specific htmx headers match, allowing different content for the same URL based on htmx triggers or targets. ```razor @* SearchResults.razor *@ @* Standard Blazor route — full page render *@ @page "/search" @* Direct htmx route — only matches when HX-Target is "results-list" *@ @attribute [HtmxRoute("/search", Target = "results-list")] @* Route triggered only from the /products page *@ @attribute [HtmxRoute("/search", CurrentURL = "/products")] @inject HtmxContext Htmx @if (Htmx.Request.RoutingMode == RoutingMode.Direct) { @* Render only the results fragment *@
    @foreach (var item in Results) {
  • @item
  • }
} else { @* Full page render *@

Search

    } @code { private List Results = ["Apple", "Banana", "Cherry"]; } ``` -------------------------------- ### Using HtmxResponse Fluent API in Blazor Source: https://context7.com/egil/htmxor/llms.txt Chain HtmxResponse methods for setting HTMX-specific response headers. All methods return 'this' for chaining. This API is useful for controlling client-side behavior after a server-side action. ```razor @* OrderForm.razor *@ @inject HtmxContext Htmx
    @code { private void OnPost(HtmxEventArgs e) { bool success = ProcessOrder(); if (success) { e.Response .PushUrl("/order/confirmation") // push URL to history .Trigger("orderPlaced", new { OrderId = 42 }, TriggerTiming.AfterSwap) .Reswap(new SwapStyleBuilder(SwapStyle.outerHTML) .AfterSwapDelay(TimeSpan.FromMilliseconds(200)) .ShowWindowTop()); } else { e.Response .StatusCode(System.Net.HttpStatusCode.UnprocessableEntity) .Retarget("#error-banner") // redirect swap to a different element .Reselect("#error-message") // use only part of the response HTML .PreventBrowserHistoryUpdate(); } } private bool ProcessOrder() => true; } ``` -------------------------------- ### Handling HTMX Requests in Blazor with HtmxContext Source: https://context7.com/egil/htmxor/llms.txt Use HtmxContext to access request details and control the response in Blazor components. Ensure HtmxContext is injected. All HtmxResponse methods will throw an exception if called during a non-HTMX request. ```razor @* Counter.razor *@ @page "/counter" @inject HtmxContext Htmx

    Counter: @count

    @code { private int count = 0; // Blazor htmx event handler — fires on POST from htmx private void OnPost(HtmxEventArgs e) { count++; // Inspect the request bool isHtmx = e.Request.IsHtmxRequest; // true string? triggerId = e.Request.Trigger; // "increment-btn" // Control the response e.Response .PushUrl($"/counter?count={count}") // update browser URL .Trigger("counterUpdated") // fire a client-side event .Reswap(SwapStyle.outerHTML); // override swap style } } ``` -------------------------------- ### HtmxHeadOutlet Component for App.razor Source: https://context7.com/egil/htmxor/llms.txt Injects the htmx JavaScript bundle and a htmx-config meta tag into the head of your Blazor application. Set UseEmbeddedHtmx to false to load htmx from a CDN. ```razor @* App.razor *@ @* Injects htmx scripts and htmx-config meta tag *@ @* Set UseEmbeddedHtmx="false" if you load htmx from a CDN *@ @* *@ @* blazor.web.js is intentionally removed — htmx handles interactivity *@ ``` -------------------------------- ### Conditional Rendering with HtmxFragment Component Source: https://context7.com/egil/htmxor/llms.txt The HtmxFragment component renders its content conditionally based on HTMX request types and optional match predicates. Use RenderDuringStandardRequest to control rendering during full-page loads. ```razor @* ProductCard.razor *@ @page "/products/{Id:int}" @attribute [HtmxRoute("/products/{Id:int}", Target = "product-detail")]

    Products

    @* This renders on full-page load only *@
    • Product 1
    • Product 2
    @* This fragment only renders when HX-Target matches "product-detail" *@

    Product @Id Details

    Description for product @Id.

    @code { [Parameter] public int Id { get; set; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.