SwapView - Intelligent Request Handling
Auto-detect HTMX requests and return partials or full pages automatically.
Overview
SwapView is the foundation of Swap.Htmx. It automatically detects whether a request comes from HTMX or a regular browser, returning just the partial for HTMX requests and the full page with layout for direct navigation.
Write your view once. It works everywhere.
Basic Usage
public class ProductsController : SwapController
{
public IActionResult Index()
{
var products = _productService.GetAll();
return SwapView(products); // Returns Index.cshtml
}
}
How It Works
- HTMX request (
HX-Requestheader present): Returns only the view content - Browser navigation (direct URL access): Returns view wrapped in layout
- Bookmarkable: Every HTMX-loaded URL can be accessed directly
Specifying View Names
// Use a specific view name
public IActionResult Details(int id)
{
var product = _productService.GetById(id);
return SwapView("ProductDetails", product);
}
// Use a partial view
public IActionResult ProductList()
{
var products = _productService.GetAll();
return SwapView("_ProductList", products);
}
Benefits
1. No Duplicate Views
Traditional approach requires separate views for partials and full pages:
Views/
Products/
Index.cshtml # Full page
_IndexPartial.cshtml # HTMX partial (duplicate!)
With SwapView, you only need one:
Views/
Products/
Index.cshtml # Works for both!
2. Progressive Enhancement
Users can bookmark and share any URL, even if it was originally loaded via HTMX:
https://myapp.com/products/42
Works whether accessed directly or through HTMX navigation.
3. Simplified Testing
Test one view for both scenarios instead of maintaining two separate views.
Advanced: Custom Layout Behavior
Control layout suppression per-request:
public IActionResult Special()
{
// Force no layout even for browser requests
ViewData["SuppressLayout"] = true;
return SwapView();
}
Or in _ViewStart.cshtml:
@using Swap.Htmx
@{
Layout = Context.ShouldSuppressLayout() ? null : "_Layout";
}
Tips
- Use meaningful view names:
SwapView("_ProductCard", product)is clearer thanSwapView("_PC", product) - Leverage Source Generators: Use
SwapViews.Products.Indexinstead of magic strings - Keep partials focused: One responsibility per partial makes them easier to reuse
Related
- SwapResponse - Multi-target updates
- Navigation Guide - SPA-style routing