From cfc11547dd42e0e1dd0e6e90e6be5a48e1a118ee Mon Sep 17 00:00:00 2001 From: rameel Date: Mon, 26 Oct 2026 16:11:56 +0500 Subject: [PATCH 1/2] docs: tidy up table and code example formatting --- docs/api/index.md | 20 +++---- docs/articles/antiforgery.md | 12 ++-- docs/articles/choosing-version.md | 16 ++--- docs/articles/configuration-v1.md | 18 +++--- docs/articles/configuration-v2.md | 22 +++---- docs/articles/configuration-v4.md | 30 +++++----- docs/articles/loading-and-errors.md | 10 ++-- docs/articles/overview.md | 44 +++++++------- docs/articles/pages-and-fragments.md | 7 ++- docs/articles/requests.md | 24 ++++---- docs/articles/responses.md | 22 +++---- docs/articles/samples.md | 24 ++++---- docs/articles/tag-helpers.md | 34 +++++------ docs/articles/version-compatibility.md | 60 +++++++++---------- docs/index.md | 14 ++--- .../requests/HtmxRequestAttributeExample.cs | 2 +- docs/snippets/requests/VaryByHtmxHeaders.cs | 9 +-- .../responses/ExposeResponseHeaders.cs | 15 ++--- .../responses/HtmxResponseAttributeExample.cs | 6 +- docs/snippets/responses/LocationWithValues.cs | 21 ++++--- docs/snippets/responses/TriggerClientEvent.cs | 6 +- 21 files changed, 212 insertions(+), 204 deletions(-) diff --git a/docs/api/index.md b/docs/api/index.md index 0e90dba..aac07b8 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -3,16 +3,16 @@ Find types by the task you want to perform. Each API page lists its members, accepted values, and remarks; the guides show how those pieces fit into an application. -| Task | Main types | Guide | -|---|---|---| -| Detect HTMX requests and read headers | [HttpRequestExtensions](xref:Ramstack.HtmxToolkit.HttpRequestExtensions), [HtmxRequestHeaders](xref:Ramstack.HtmxToolkit.HtmxRequestHeaders) | [Requests](../articles/requests.md) | -| Set response headers, navigation, and events | [HttpResponseExtensions](xref:Ramstack.HtmxToolkit.HttpResponseExtensions), [HtmxResponse](xref:Ramstack.HtmxToolkit.HtmxResponse), [HtmxResponseHeaders](xref:Ramstack.HtmxToolkit.HtmxResponseHeaders) | [Responses](../articles/responses.md) | -| Set swap styles, event timing, or a follow-up request | [HtmxSwap](xref:Ramstack.HtmxToolkit.HtmxSwap), [HtmxTriggerTiming](xref:Ramstack.HtmxToolkit.HtmxTriggerTiming), [HtmxLocationOptions](xref:Ramstack.HtmxToolkit.HtmxLocationOptions) | [Response instructions](../articles/responses.md#choose-a-response-instruction) | -| Select or configure MVC actions | [HtmxRequestAttribute](xref:Ramstack.HtmxToolkit.HtmxRequestAttribute), [HtmxResponseAttribute](xref:Ramstack.HtmxToolkit.HtmxResponseAttribute) | [MVC action selection](../articles/requests.md#select-mvc-actions-declaratively) | -| Generate URLs in Razor | [HtmxUrlTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxUrlTagHelper) | [Request URLs](../articles/tag-helpers.md#generate-request-urls) | -| Add values, headers, or request options | [HtmxValsTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxValsTagHelper), [HtmxHeaderTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxHeaderTagHelper), [HtmxRequestTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxRequestTagHelper) | [Tag Helpers](../articles/tag-helpers.md) | -| Register the toolkit and render configuration | [ServiceCollectionExtensions](xref:Ramstack.HtmxToolkit.Hosting.ServiceCollectionExtensions), [HtmxToolkitOptions](xref:Ramstack.HtmxToolkit.Configuration.HtmxToolkitOptions), [HtmxConfigTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxConfigTagHelper) | [Configuration](../articles/configuration.md) | -| Configure a specific HTMX version | [HtmxV1Config](xref:Ramstack.HtmxToolkit.Configuration.HtmxV1Config), [HtmxV2Config](xref:Ramstack.HtmxToolkit.Configuration.HtmxV2Config), [HtmxV4Config](xref:Ramstack.HtmxToolkit.Configuration.HtmxV4Config) | [Choose a version](../articles/choosing-version.md) | +| Task | Main types | Guide | +|-------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------| +| Detect HTMX requests and read headers | [HttpRequestExtensions](xref:Ramstack.HtmxToolkit.HttpRequestExtensions), [HtmxRequestHeaders](xref:Ramstack.HtmxToolkit.HtmxRequestHeaders) | [Requests](../articles/requests.md) | +| Set response headers, navigation, and events | [HttpResponseExtensions](xref:Ramstack.HtmxToolkit.HttpResponseExtensions), [HtmxResponse](xref:Ramstack.HtmxToolkit.HtmxResponse), [HtmxResponseHeaders](xref:Ramstack.HtmxToolkit.HtmxResponseHeaders) | [Responses](../articles/responses.md) | +| Set swap styles, event timing, or a follow-up request | [HtmxSwap](xref:Ramstack.HtmxToolkit.HtmxSwap), [HtmxTriggerTiming](xref:Ramstack.HtmxToolkit.HtmxTriggerTiming), [HtmxLocationOptions](xref:Ramstack.HtmxToolkit.HtmxLocationOptions) | [Response instructions](../articles/responses.md#choose-a-response-instruction) | +| Select or configure MVC actions | [HtmxRequestAttribute](xref:Ramstack.HtmxToolkit.HtmxRequestAttribute), [HtmxResponseAttribute](xref:Ramstack.HtmxToolkit.HtmxResponseAttribute) | [MVC action selection](../articles/requests.md#select-mvc-actions-declaratively) | +| Generate URLs in Razor | [HtmxUrlTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxUrlTagHelper) | [Request URLs](../articles/tag-helpers.md#generate-request-urls) | +| Add values, headers, or request options | [HtmxValsTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxValsTagHelper), [HtmxHeaderTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxHeaderTagHelper), [HtmxRequestTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxRequestTagHelper) | [Tag Helpers](../articles/tag-helpers.md) | +| Register the toolkit and render configuration | [ServiceCollectionExtensions](xref:Ramstack.HtmxToolkit.Hosting.ServiceCollectionExtensions), [HtmxToolkitOptions](xref:Ramstack.HtmxToolkit.Configuration.HtmxToolkitOptions), [HtmxConfigTagHelper](xref:Ramstack.HtmxToolkit.TagHelpers.HtmxConfigTagHelper) | [Configuration](../articles/configuration.md) | +| Configure a specific HTMX version | [HtmxV1Config](xref:Ramstack.HtmxToolkit.Configuration.HtmxV1Config), [HtmxV2Config](xref:Ramstack.HtmxToolkit.Configuration.HtmxV2Config), [HtmxV4Config](xref:Ramstack.HtmxToolkit.Configuration.HtmxV4Config) | [Choose a version](../articles/choosing-version.md) | New to the library? Start with [Getting started](../articles/getting-started.md) for a working Razor Pages application, or choose the [MVC](../articles/mvc.md) or [Minimal API](../articles/minimal-apis.md) example. diff --git a/docs/articles/antiforgery.md b/docs/articles/antiforgery.md index 6f7fe28..26a150d 100644 --- a/docs/articles/antiforgery.md +++ b/docs/articles/antiforgery.md @@ -9,12 +9,12 @@ The Toolkit script, `htmx-toolkit.min.js`, comes with the package as a static we It is not the HTMX library itself. Load it after HTMX on every page that uses HTMX; see [Static assets and deployment](static-assets.md) for the URL and caching. -| Feature | HTMX versions | Without the script | -|---|---|---| -| Adds the antiforgery token to non-GET HTMX requests and refreshes it after boosted navigation | All | Non-GET requests without a token field fail server-side antiforgery validation, usually with HTTP 400 | -| Sends `HX-Request-Type`; see [Check full or partial requests](requests.md#check-full-or-partial-requests) | 1.9.x and 2.x; HTMX 4.x sends it itself | `IsHtmxPartialRequest()` and `IsHtmxFullRequest()` return `false`, and `[HtmxRequest]` with a `RequestType` does not match | -| Replays events whose name repeats in one response header; see [Timing and repeated events](responses.md#timing-and-repeated-events) | All | None of the events in that header fire | -| Adds the `ramstack-swap` extension with `innerMorph`, `outerMorph`, and a simplified `outerSync`, plus `textContent` for HTMX 1.9.x; see [Morph swaps](version-compatibility.md#morph-swaps) | 1.9.x and 2.x; HTMX 4.x supports these swap styles natively | These swap styles are not available | +| Feature | HTMX versions | Without the script | +|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------| +| Adds the antiforgery token to non-GET HTMX requests and refreshes it after boosted navigation | All | Non-GET requests without a token field fail server-side antiforgery validation, usually with HTTP 400 | +| Sends `HX-Request-Type`; see [Check full or partial requests](requests.md#check-full-or-partial-requests) | 1.9.x and 2.x; HTMX 4.x sends it itself | `IsHtmxPartialRequest()` and `IsHtmxFullRequest()` return `false`, and `[HtmxRequest]` with a `RequestType` does not match | +| Replays events whose name repeats in one response header; see [Timing and repeated events](responses.md#timing-and-repeated-events) | All | None of the events in that header fire | +| Adds the `ramstack-swap` extension with `innerMorph`, `outerMorph`, and a simplified `outerSync`, plus `textContent` for HTMX 1.9.x; see [Morph swaps](version-compatibility.md#morph-swaps) | 1.9.x and 2.x; HTMX 4.x supports these swap styles natively | These swap styles are not available | ## How automatic antiforgery works diff --git a/docs/articles/choosing-version.md b/docs/articles/choosing-version.md index cb25851..00086be 100644 --- a/docs/articles/choosing-version.md +++ b/docs/articles/choosing-version.md @@ -36,14 +36,14 @@ trying to select a different version causes startup validation to fail. ## What the selection changes -| Behavior | HTMX 1.9.x | HTMX 2.x | HTMX 4.x | -|---|---|---|---| -| Default when omitted | No | Yes | No | -| Global config type | `HtmxV1Config` | `HtmxV2Config` | `HtmxV4Config` | -| Per-request attribute | `hx-request` | `hx-request` | `hx-config` | -| Triggering element header | `HX-Trigger` | `HX-Trigger` | `HX-Source` | -| Expected response kind | `HX-Request-Type` from the Toolkit script | `HX-Request-Type` from the Toolkit script | `HX-Request-Type` | -| Morph swap support | Toolkit compatibility extension | Toolkit compatibility extension | Native | +| Behavior | HTMX 1.9.x | HTMX 2.x | HTMX 4.x | +|---------------------------|-------------------------------------------|-------------------------------------------|-------------------| +| Default when omitted | No | Yes | No | +| Global config type | `HtmxV1Config` | `HtmxV2Config` | `HtmxV4Config` | +| Per-request attribute | `hx-request` | `hx-request` | `hx-config` | +| Triggering element header | `HX-Trigger` | `HX-Trigger` | `HX-Source` | +| Expected response kind | `HX-Request-Type` from the Toolkit script | `HX-Request-Type` from the Toolkit script | `HX-Request-Type` | +| Morph swap support | Toolkit compatibility extension | Toolkit compatibility extension | Native | See [Version compatibility](version-compatibility.md) for the differences that affect application code. diff --git a/docs/articles/configuration-v1.md b/docs/articles/configuration-v1.md index e777e0c..2bb2272 100644 --- a/docs/articles/configuration-v1.md +++ b/docs/articles/configuration-v1.md @@ -23,16 +23,16 @@ Only non-null settings are written to ``. ## Settings by purpose -| Purpose | Properties | -|---|---| -| History | `HistoryEnabled`, `HistoryCacheSize`, `RefreshOnHistoryMiss` | -| Swaps | `DefaultSwapStyle`, `DefaultSwapDelay`, `DefaultSettleDelay`, `AttributesToSettle` | +| Purpose | Properties | +|------------------------------|------------------------------------------------------------------------------------------------------------| +| History | `HistoryEnabled`, `HistoryCacheSize`, `RefreshOnHistoryMiss` | +| Swaps | `DefaultSwapStyle`, `DefaultSwapDelay`, `DefaultSettleDelay`, `AttributesToSettle` | | Indicators and lifecycle CSS | `IncludeIndicatorStyles`, `IndicatorClass`, `RequestClass`, `AddedClass`, `SwappingClass`, `SettlingClass` | -| Script and content security | `AllowEval`, `AllowScriptTags`, `InlineScriptNonce`, `DisableSelector` | -| Requests | `WithCredentials`, `Timeout`, `SelfRequestsOnly`, `MethodsThatUseUrlParams`, `GetCacheBusterParam` | -| Navigation and focus | `ScrollBehavior`, `DefaultFocusScroll`, `ScrollIntoViewOnBoost`, `IgnoreTitle` | -| Transitions and parsing | `GlobalViewTransitions`, `UseTemplateFragments`, `TriggerSpecsCacheEnabled` | -| WebSocket | `WsBinaryType` | +| Script and content security | `AllowEval`, `AllowScriptTags`, `InlineScriptNonce`, `DisableSelector` | +| Requests | `WithCredentials`, `Timeout`, `SelfRequestsOnly`, `MethodsThatUseUrlParams`, `GetCacheBusterParam` | +| Navigation and focus | `ScrollBehavior`, `DefaultFocusScroll`, `ScrollIntoViewOnBoost`, `IgnoreTitle` | +| Transitions and parsing | `GlobalViewTransitions`, `UseTemplateFragments`, `TriggerSpecsCacheEnabled` | +| WebSocket | `WsBinaryType` | `wsReconnectDelay` is not exposed: in JSON, HTMX accepts only its default value `"full-jitter"`. To customize the WebSocket reconnection delay, assign a function to `htmx.config.wsReconnectDelay` in JavaScript. diff --git a/docs/articles/configuration-v2.md b/docs/articles/configuration-v2.md index 097ffc0..87bf030 100644 --- a/docs/articles/configuration-v2.md +++ b/docs/articles/configuration-v2.md @@ -21,17 +21,17 @@ builder.Services.AddHtmxToolkit(options => ## Settings by purpose -| Purpose | Properties | -|---|---| -| History | `HistoryEnabled`, `HistoryCacheSize`, `RefreshOnHistoryMiss`, `HistoryRestoreAsHxRequest` | -| Swaps | `DefaultSwapStyle`, `DefaultSwapDelay`, `DefaultSettleDelay`, `AttributesToSettle`, `AllowNestedOobSwaps` | -| Indicators and lifecycle CSS | `IncludeIndicatorStyles`, `IndicatorClass`, `RequestClass`, `AddedClass`, `SwappingClass`, `SettlingClass` | -| Script and content security | `AllowEval`, `AllowScriptTags`, `InlineScriptNonce`, `InlineStyleNonce`, `DisableSelector` | -| Requests | `WithCredentials`, `DisableInheritance`, `Timeout`, `SelfRequestsOnly`, `MethodsThatUseUrlParams`, `GetCacheBusterParam` | -| Navigation and focus | `ScrollBehavior`, `DefaultFocusScroll`, `ScrollIntoViewOnBoost`, `IgnoreTitle` | -| Transitions and forms | `GlobalViewTransitions`, `TriggerSpecsCacheEnabled`, `ReportValidityOfForms` | -| Responses | `ResponseHandling` | -| WebSocket | `WsBinaryType` | +| Purpose | Properties | +|------------------------------|--------------------------------------------------------------------------------------------------------------------------| +| History | `HistoryEnabled`, `HistoryCacheSize`, `RefreshOnHistoryMiss`, `HistoryRestoreAsHxRequest` | +| Swaps | `DefaultSwapStyle`, `DefaultSwapDelay`, `DefaultSettleDelay`, `AttributesToSettle`, `AllowNestedOobSwaps` | +| Indicators and lifecycle CSS | `IncludeIndicatorStyles`, `IndicatorClass`, `RequestClass`, `AddedClass`, `SwappingClass`, `SettlingClass` | +| Script and content security | `AllowEval`, `AllowScriptTags`, `InlineScriptNonce`, `InlineStyleNonce`, `DisableSelector` | +| Requests | `WithCredentials`, `DisableInheritance`, `Timeout`, `SelfRequestsOnly`, `MethodsThatUseUrlParams`, `GetCacheBusterParam` | +| Navigation and focus | `ScrollBehavior`, `DefaultFocusScroll`, `ScrollIntoViewOnBoost`, `IgnoreTitle` | +| Transitions and forms | `GlobalViewTransitions`, `TriggerSpecsCacheEnabled`, `ReportValidityOfForms` | +| Responses | `ResponseHandling` | +| WebSocket | `WsBinaryType` | `wsReconnectDelay` is not exposed: in JSON, the WebSocket extension accepts only its default value `"full-jitter"`. To customize the reconnection delay, assign a function to `htmx.config.wsReconnectDelay` in JavaScript. diff --git a/docs/articles/configuration-v4.md b/docs/articles/configuration-v4.md index bbec919..5c2202e 100644 --- a/docs/articles/configuration-v4.md +++ b/docs/articles/configuration-v4.md @@ -22,26 +22,26 @@ builder.Services.AddHtmxToolkit(options => ## Settings by purpose -| Purpose | Properties | -|---|---| -| Diagnostics and attribute prefix | `LogAll`, `Prefix` | -| History | `History` | -| Swaps and morphing | `DefaultSwap`, `AllowEmptySwapAfterOob`, `DefaultSettleDelay`, `MorphIgnore`, `MorphSkip`, `MorphSkipChildren`, `MorphScanLimit` | -| Indicators and lifecycle CSS | `IncludeIndicatorCss`, `IndicatorClass`, `RequestClass` | -| Script and extensions | `InlineScriptNonce`, `Extensions`, `ImplicitInheritance` | -| Requests | `DefaultTimeout`, `Mode` | -| Focus and transitions | `DefaultFocusScroll`, `Transitions` | -| Responses | `NoSwap` | +| Purpose | Properties | +|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------| +| Diagnostics and attribute prefix | `LogAll`, `Prefix` | +| History | `History` | +| Swaps and morphing | `DefaultSwap`, `AllowEmptySwapAfterOob`, `DefaultSettleDelay`, `MorphIgnore`, `MorphSkip`, `MorphSkipChildren`, `MorphScanLimit` | +| Indicators and lifecycle CSS | `IncludeIndicatorCss`, `IndicatorClass`, `RequestClass` | +| Script and extensions | `InlineScriptNonce`, `Extensions`, `ImplicitInheritance` | +| Requests | `DefaultTimeout`, `Mode` | +| Focus and transitions | `DefaultFocusScroll`, `Transitions` | +| Responses | `NoSwap` | ## Request mode `Mode` maps to the Fetch API request mode: -| Value | Meaning | -|---|---| -| `SameOrigin` | Allow only same-origin requests | -| `Cors` | Allow cross-origin requests through CORS | -| `NoCors` | Allow restricted cross-origin requests that produce opaque responses | +| Value | Meaning | +|--------------|----------------------------------------------------------------------| +| `SameOrigin` | Allow only same-origin requests | +| `Cors` | Allow cross-origin requests through CORS | +| `NoCors` | Allow restricted cross-origin requests that produce opaque responses | In `NoCors` mode, the browser allows only `GET`, `HEAD`, and `POST`; other methods raise `htmx:error`. It also removes request headers that are not CORS-safelisted, even for same-origin requests: the server receives diff --git a/docs/articles/loading-and-errors.md b/docs/articles/loading-and-errors.md index b4e3e43..1ba079b 100644 --- a/docs/articles/loading-and-errors.md +++ b/docs/articles/loading-and-errors.md @@ -122,11 +122,11 @@ The controller does not need extra response headers for this browser feedback. The JavaScript above uses HTMX 2.x lifecycle events. HTMX 4 changes their names and event data: -| Purpose | HTMX 2.x | HTMX 4.x | -|---|---|---| -| Clear the previous error before sending | `htmx:beforeRequest` | `htmx:before:request` | -| Report an HTTP error | `htmx:responseError` | `htmx:response:error` | -| Report a connection failure or timeout | `htmx:sendError`, `htmx:timeout` | `htmx:error` | +| Purpose | HTMX 2.x | HTMX 4.x | +|-----------------------------------------|----------------------------------|-----------------------| +| Clear the previous error before sending | `htmx:beforeRequest` | `htmx:before:request` | +| Report an HTTP error | `htmx:responseError` | `htmx:response:error` | +| Report a connection failure or timeout | `htmx:sendError`, `htmx:timeout` | `htmx:error` | When porting the listeners, read the request context from `event.detail.ctx`; response status is available as `ctx.response.status` when a response exists. `htmx:error` also covers exceptions during a swap, so inspect diff --git a/docs/articles/overview.md b/docs/articles/overview.md index 41ff724..acda13b 100644 --- a/docs/articles/overview.md +++ b/docs/articles/overview.md @@ -11,12 +11,12 @@ The server renders the new HTML; you do not need to build that HTML from JSON in Four attributes describe most interactions: -| Attribute | What it controls | Example | -|---|---|---| +| Attribute | What it controls | Example | +|-----------------------|----------------------------|--------------------------------------------| | `hx-get` or `hx-post` | The request method and URL | `hx-get="/Products?handler=Details&id=42"` | -| `hx-trigger` | When to send the request | `hx-trigger="click"` | -| `hx-target` | The element to update | `hx-target="#product-details"` | -| `hx-swap` | How to insert the response | `hx-swap="innerHTML"` | +| `hx-trigger` | When to send the request | `hx-trigger="click"` | +| `hx-target` | The element to update | `hx-target="#product-details"` | +| `hx-swap` | How to insert the response | `hx-swap="innerHTML"` | A button uses `click` by default, and a form uses `submit`. The default swap is `innerHTML`, which replaces the target's contents and keeps the target itself. `outerHTML` replaces the target element too, so the response @@ -27,15 +27,15 @@ and response headers that tell HTMX what to do next. ## What the toolkit provides -| Area | Toolkit feature | -|---|---| -| Incoming requests | `IsHtmxPartialRequest`, `IsHtmxFullRequest`, `IsHtmxRequest`, `IsHtmxBoosted`, and strongly typed request headers | -| Outgoing responses | Fluent `Response.Htmx(...)` API and strongly typed response headers | -| MVC | `[HtmxRequest]` action selection by request type and boosted navigation, and `[HtmxResponse]` response configuration | -| Razor | Tag Helpers for routes, values, headers, and per-request options | -| Configuration | Version-specific HTMX configuration rendered by `` | -| Security | Automatic ASP.NET Core antiforgery headers for unsafe HTMX requests | -| Browser script | The [Toolkit script](antiforgery.md#what-the-toolkit-script-does), served as a static web asset and loaded from the layout | +| Area | Toolkit feature | +|--------------------|----------------------------------------------------------------------------------------------------------------------------| +| Incoming requests | `IsHtmxPartialRequest`, `IsHtmxFullRequest`, `IsHtmxRequest`, `IsHtmxBoosted`, and strongly typed request headers | +| Outgoing responses | Fluent `Response.Htmx(...)` API and strongly typed response headers | +| MVC | `[HtmxRequest]` action selection by request type and boosted navigation, and `[HtmxResponse]` response configuration | +| Razor | Tag Helpers for routes, values, headers, and per-request options | +| Configuration | Version-specific HTMX configuration rendered by `` | +| Security | Automatic ASP.NET Core antiforgery headers for unsafe HTMX requests | +| Browser script | The [Toolkit script](antiforgery.md#what-the-toolkit-script-does), served as a static web asset and loaded from the layout | HtmxToolkit does not include the HTMX library and does not replace HTMX attributes such as `hx-target`, `hx-trigger`, or `hx-swap`. Add a supported HTMX release to the application separately. @@ -90,14 +90,14 @@ registration, and layout needed to run it. ## Which pieces do I need? -| Application feature | Setup | -|---|---| -| Read request headers or set ordinary response headers | Reference the package and import `Ramstack.HtmxToolkit` in C# | -| Choose a target version or configure HTMX | Call `AddHtmxToolkit()`; render `` in Razor for browser configuration | -| Generate URLs or JSON attributes in Razor | Register the toolkit Tag Helpers in `_ViewImports.cshtml` | -| Attach antiforgery tokens automatically | Render configuration metadata, load the Toolkit script, and enable server validation | -| Use compatibility morph swaps or replay duplicate event names | Load the Toolkit script; follow the relevant feature's setup | -| Tell full-page and fragment requests apart with HTMX 1.9.x or 2.x | Load the Toolkit script | +| Application feature | Setup | +|-------------------------------------------------------------------|--------------------------------------------------------------------------------------| +| Read request headers or set ordinary response headers | Reference the package and import `Ramstack.HtmxToolkit` in C# | +| Choose a target version or configure HTMX | Call `AddHtmxToolkit()`; render `` in Razor for browser configuration | +| Generate URLs or JSON attributes in Razor | Register the toolkit Tag Helpers in `_ViewImports.cshtml` | +| Attach antiforgery tokens automatically | Render configuration metadata, load the Toolkit script, and enable server validation | +| Use compatibility morph swaps or replay duplicate event names | Load the Toolkit script; follow the relevant feature's setup | +| Tell full-page and fragment requests apart with HTMX 1.9.x or 2.x | Load the Toolkit script | For HTMX 4.x, register the target version even if you only use response events, so the toolkit chooses the correct trigger headers. In a pure Minimal API application, HTML rendering and token metadata are supplied diff --git a/docs/articles/pages-and-fragments.md b/docs/articles/pages-and-fragments.md index 133d367..0eb1403 100644 --- a/docs/articles/pages-and-fragments.md +++ b/docs/articles/pages-and-fragments.md @@ -155,8 +155,11 @@ On ASP.NET Core 7 or later, a policy for public, cacheable HTML could include: ```csharp builder.Services.AddOutputCache(options => { - options.AddPolicy("HtmxHtml", policy => policy.SetVaryByHeader( - "HX-Request", "HX-History-Restore-Request", "HX-Request-Type")); + options.AddPolicy("HtmxHtml", policy => + policy.SetVaryByHeader( + "HX-Request", + "HX-History-Restore-Request", + "HX-Request-Type")); }); ``` diff --git a/docs/articles/requests.md b/docs/articles/requests.md index 42e009d..ca580e3 100644 --- a/docs/articles/requests.md +++ b/docs/articles/requests.md @@ -43,17 +43,17 @@ var htmx = Request.GetHtmxHeaders(); ## Request header properties -| Property | Meaning | -|---|---| -| `Request` | Whether the `HX-Request` header is present | -| `Boosted` | Whether a regular navigation was enhanced by `hx-boost` | -| `CurrentUrl` | Current browser URL when the request was sent | -| `HistoryRestoreRequest` | Whether HTMX marked the request for history restoration | -| `Target` | Target element; its format differs in HTMX 4 | -| `Prompt` | Result of `hx-prompt`; in HTMX 4.x, sent only by the `hx-prompt` extension | -| `Trigger`, `TriggerName` | Triggering element ID and name in HTMX 1.9.x and 2.x | -| `Source` | Triggering `tag#id` in HTMX 4.x | -| `RequestType` | `HtmxRequestType.Partial` or `HtmxRequestType.Full`; added by the Toolkit script in HTMX 1.9.x and 2.x | +| Property | Meaning | +|--------------------------|--------------------------------------------------------------------------------------------------------| +| `Request` | Whether the `HX-Request` header is present | +| `Boosted` | Whether a regular navigation was enhanced by `hx-boost` | +| `CurrentUrl` | Current browser URL when the request was sent | +| `HistoryRestoreRequest` | Whether HTMX marked the request for history restoration | +| `Target` | Target element; its format differs in HTMX 4 | +| `Prompt` | Result of `hx-prompt`; in HTMX 4.x, sent only by the `hx-prompt` extension | +| `Trigger`, `TriggerName` | Triggering element ID and name in HTMX 1.9.x and 2.x | +| `Source` | Triggering `tag#id` in HTMX 4.x | +| `RequestType` | `HtmxRequestType.Partial` or `HtmxRequestType.Full`; added by the Toolkit script in HTMX 1.9.x and 2.x | Missing or version-inapplicable string headers return `null`. `Request` is `true` whenever the `HX-Request` header is present, whatever its value; @@ -159,8 +159,8 @@ Without `RequestType`, the attribute accepts any HTMX request. That suits an end such as a status widget: ```csharp -[HttpGet("/inventory/{sku}")] [HtmxRequest] +[HttpGet("/inventory/{sku}")] public IActionResult InventoryFragment(string sku) => PartialView("_Inventory", inventory.Find(sku)); ``` diff --git a/docs/articles/responses.md b/docs/articles/responses.md index c233120..f690372 100644 --- a/docs/articles/responses.md +++ b/docs/articles/responses.md @@ -53,18 +53,18 @@ app.MapPost("/account/sign-in", (HttpResponse response, LinkGenerator links) => ## Choose a response instruction -| Goal | API | Header | -|---|---|---| -| Request another URL through HTMX | `Location` | `HX-Location` | -| Navigate with a full page load | `Redirect` | `HX-Redirect` | -| Reload the current page | `Refresh` | `HX-Refresh` | -| Add a browser history entry | `PushUrl` | `HX-Push-Url` | -| Replace the current history entry | `ReplaceUrl` | `HX-Replace-Url` | +| Goal | API | Header | +|-------------------------------------|------------------------|----------------------| +| Request another URL through HTMX | `Location` | `HX-Location` | +| Navigate with a full page load | `Redirect` | `HX-Redirect` | +| Reload the current page | `Refresh` | `HX-Refresh` | +| Add a browser history entry | `PushUrl` | `HX-Push-Url` | +| Replace the current history entry | `ReplaceUrl` | `HX-Replace-Url` | | Leave the browser history unchanged | `PreventHistoryUpdate` | `HX-Push-Url: false` | -| Change the swap target | `Retarget` | `HX-Retarget` | -| Change the swap strategy | `Reswap` | `HX-Reswap` | -| Select part of the response | `Reselect` | `HX-Reselect` | -| Dispatch client events | `TriggerEvent` | `HX-Trigger*` | +| Change the swap target | `Retarget` | `HX-Retarget` | +| Change the swap strategy | `Reswap` | `HX-Reswap` | +| Select part of the response | `Reselect` | `HX-Reselect` | +| Dispatch client events | `TriggerEvent` | `HX-Trigger*` | > [!TIP] > `Location`, `Redirect`, `PushUrl`, and `ReplaceUrl` take a URL string. Generate it with `Url.Action`, `Url.Page`, diff --git a/docs/articles/samples.md b/docs/articles/samples.md index 838eb78..2681345 100644 --- a/docs/articles/samples.md +++ b/docs/articles/samples.md @@ -26,18 +26,18 @@ version-specific options such as `NoSwap`. Each Razor Page has a `.cshtml` file for the browser markup and a `.cshtml.cs` file for its handlers. Start with the linked page, then open its code-behind file in the same directory. -| Task | Demo page | Related guide | -|---|---|---| -| Generate a page-handler URL | [UrlTagHelper](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/UrlTagHelper.cshtml) | [Tag Helpers](tag-helpers.md#generate-request-urls) | -| Send route values | [RouteData](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/RouteData.cshtml) | [Routes and dictionaries](tag-helpers.md#named-routes-and-route-dictionaries) | -| Send values and custom headers | [HtmxVals](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/HtmxVals.cshtml), [Headers](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/Headers.cshtml) | [Tag Helpers](tag-helpers.md#send-additional-values) | -| Set request options | [RequestOptions](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/RequestOptions.cshtml) | [Configure one request](tag-helpers.md#configure-one-request) | -| Detect HTMX and boosted requests | [HtmxRequest](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/HtmxRequest.cshtml), [Boosted](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/Boosted.cshtml) | [Requests](requests.md) | -| Use MVC attributes | [InventoryController](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Controllers/InventoryController.cs) | [MVC action selection](requests.md#select-mvc-actions-declaratively) | -| Change the response target | [FluentResponse](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/FluentResponse.cshtml) | [Responses](responses.md) | -| Trigger another update | [ServerEvents](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/ServerEvents.cshtml) | [Forms and events tutorial](forms-and-validation.md) | -| Poll until work completes | [Polling](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/Polling.cshtml) | [Polling recipe](recipes.md#poll-a-background-operation) | -| Submit a protected form | [Antiforgery](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/Antiforgery.cshtml) | [Antiforgery](antiforgery.md) | +| Task | Demo page | Related guide | +|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------| +| Generate a page-handler URL | [UrlTagHelper](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/UrlTagHelper.cshtml) | [Tag Helpers](tag-helpers.md#generate-request-urls) | +| Send route values | [RouteData](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/RouteData.cshtml) | [Routes and dictionaries](tag-helpers.md#named-routes-and-route-dictionaries) | +| Send values and custom headers | [HtmxVals](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/HtmxVals.cshtml), [Headers](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/Headers.cshtml) | [Tag Helpers](tag-helpers.md#send-additional-values) | +| Set request options | [RequestOptions](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/RequestOptions.cshtml) | [Configure one request](tag-helpers.md#configure-one-request) | +| Detect HTMX and boosted requests | [HtmxRequest](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/HtmxRequest.cshtml), [Boosted](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/Boosted.cshtml) | [Requests](requests.md) | +| Use MVC attributes | [InventoryController](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Controllers/InventoryController.cs) | [MVC action selection](requests.md#select-mvc-actions-declaratively) | +| Change the response target | [FluentResponse](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/FluentResponse.cshtml) | [Responses](responses.md) | +| Trigger another update | [ServerEvents](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/ServerEvents.cshtml) | [Forms and events tutorial](forms-and-validation.md) | +| Poll until work completes | [Polling](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/Polling.cshtml) | [Polling recipe](recipes.md#poll-a-background-operation) | +| Submit a protected form | [Antiforgery](https://github.com/rameel/ramstack.htmxtoolkit/blob/main/samples/Ramstack.HtmxToolkit.Demo/Pages/Examples/Antiforgery.cshtml) | [Antiforgery](antiforgery.md) | ## Inspect the browser behavior diff --git a/docs/articles/tag-helpers.md b/docs/articles/tag-helpers.md index a67f29e..a893c95 100644 --- a/docs/articles/tag-helpers.md +++ b/docs/articles/tag-helpers.md @@ -208,16 +208,16 @@ The output depends on the configured HTMX target: