From 631d3968fe927a591be586c339be09506ebc4e45 Mon Sep 17 00:00:00 2001 From: rameel Date: Tue, 27 Oct 2026 23:11:28 +0500 Subject: [PATCH] tag-helpers: remove asp-host and asp-protocol from HtmxUrlTagHelper --- docs/articles/migrate-to-v2.md | 10 +++-- .../TagHelpers/HtmxUrlTagHelper.cs | 40 ++++--------------- 2 files changed, 14 insertions(+), 36 deletions(-) diff --git a/docs/articles/migrate-to-v2.md b/docs/articles/migrate-to-v2.md index 0709eec..cb1b04f 100644 --- a/docs/articles/migrate-to-v2.md +++ b/docs/articles/migrate-to-v2.md @@ -20,7 +20,7 @@ step; see [Version compatibility](version-compatibility.md) for that. | [Global configuration](#move-global-configuration-to-code) | `` attributes move to `AddHtmxToolkit()` | **Silent** | | [Antiforgery](#antiforgery-metadata-is-on-by-default) | Metadata is included by default and no longer stored in `htmx.config` | **Silent** | | [Toolkit script](#load-the-toolkit-script-as-a-static-asset) | Inline script helpers and `MapHtmxAntiforgeryScript` replaced by a static web asset | Build | -| [URL Tag Helper](#rename-the-url-tag-helper-attributes) | `hx-controller`, `hx-action`, `hx-route-*`, and similar become `asp-*` | **Silent** | +| [URL Tag Helper](#rename-the-url-tag-helper-attributes) | `hx-*` URL attributes become `asp-*`; `hx-host` and `hx-protocol` are removed | **Silent** | | [Requests](#update-request-handling) | `IsHtmxRequest()` is `false` for history restoration; `Boosted` filter renamed | Build, **silent** | | [Action result wrappers](#configure-responses-through-responsehtmx) | `IActionResult.Htmx(...)` removed | Build | | [Polling](#replace-stoppolling) | `StopPolling` removed | Build | @@ -219,8 +219,8 @@ HTMX 4.x defines a native `hx-action` attribute, which made the old naming confl | `hx-route` | `asp-route` | | `hx-route-*` | `asp-route-*` | | `hx-all-route-data` | `asp-all-route-data` | -| `hx-host` | `asp-host` | -| `hx-protocol` | `asp-protocol` | +| `hx-host` | Removed | +| `hx-protocol` | Removed | | `hx-fragment` | `asp-fragment` | The HTMX request attribute is now required and must be written without a value. In 1.x, `hx-get` was used @@ -283,6 +283,10 @@ Check the following while migrating: See [Links, forms, and buttons](tag-helpers.md#links-forms-and-buttons). - **An HTMX request attribute with a value throws** when `asp-*` attributes are present, even an empty one such as `hx-get=""`. An `hx-get="/url"` without `asp-*` attributes is not affected. +- **`hx-host` and `hx-protocol` have no replacement.** They only made the URL absolute, and HTMX 2.x and 4.x + block cross-origin requests by default. For a request to another origin, allow it in the HTMX configuration + and write the URL directly, for example + `hx-get="@Url.Action("Detail", "Speaker", new { id = Model.SpeakerId }, "https", "api.example.com")"`. - **The Tag Helper order** changed from `-1000` to `-950`, so it runs after the built-in Tag Helpers. This matters only to custom Tag Helpers that depend on that order. diff --git a/src/Ramstack.HtmxToolkit/TagHelpers/HtmxUrlTagHelper.cs b/src/Ramstack.HtmxToolkit/TagHelpers/HtmxUrlTagHelper.cs index da5d69d..48cc51f 100644 --- a/src/Ramstack.HtmxToolkit/TagHelpers/HtmxUrlTagHelper.cs +++ b/src/Ramstack.HtmxToolkit/TagHelpers/HtmxUrlTagHelper.cs @@ -26,7 +26,7 @@ namespace Ramstack.HtmxToolkit.TagHelpers; /// hx-patch, hx-delete, or HTMX 4.x hx-action attribute together with /// at least one of the asp-action, asp-controller, asp-area, asp-page, /// asp-page-handler, asp-route, asp-route-*, asp-all-route-data, -/// asp-host, asp-protocol, or asp-fragment attributes. +/// or asp-fragment attributes. /// The generated URL is written to the HTMX attribute, which must not have a value. /// /// @@ -50,8 +50,6 @@ namespace Ramstack.HtmxToolkit.TagHelpers; [HtmlTargetElement(Attributes = "hx-get," + RouteAttributeName)] [HtmlTargetElement(Attributes = "hx-get," + RouteValuesDictionaryName)] [HtmlTargetElement(Attributes = "hx-get," + RouteValuesPrefix + "*")] -[HtmlTargetElement(Attributes = "hx-get," + HostAttributeName)] -[HtmlTargetElement(Attributes = "hx-get," + ProtocolAttributeName)] [HtmlTargetElement(Attributes = "hx-get," + FragmentAttributeName)] [HtmlTargetElement(Attributes = "hx-post," + ActionAttributeName)] [HtmlTargetElement(Attributes = "hx-post," + ControllerAttributeName)] @@ -61,8 +59,6 @@ namespace Ramstack.HtmxToolkit.TagHelpers; [HtmlTargetElement(Attributes = "hx-post," + RouteAttributeName)] [HtmlTargetElement(Attributes = "hx-post," + RouteValuesDictionaryName)] [HtmlTargetElement(Attributes = "hx-post," + RouteValuesPrefix + "*")] -[HtmlTargetElement(Attributes = "hx-post," + HostAttributeName)] -[HtmlTargetElement(Attributes = "hx-post," + ProtocolAttributeName)] [HtmlTargetElement(Attributes = "hx-post," + FragmentAttributeName)] [HtmlTargetElement(Attributes = "hx-put," + ActionAttributeName)] [HtmlTargetElement(Attributes = "hx-put," + ControllerAttributeName)] @@ -72,8 +68,6 @@ namespace Ramstack.HtmxToolkit.TagHelpers; [HtmlTargetElement(Attributes = "hx-put," + RouteAttributeName)] [HtmlTargetElement(Attributes = "hx-put," + RouteValuesDictionaryName)] [HtmlTargetElement(Attributes = "hx-put," + RouteValuesPrefix + "*")] -[HtmlTargetElement(Attributes = "hx-put," + HostAttributeName)] -[HtmlTargetElement(Attributes = "hx-put," + ProtocolAttributeName)] [HtmlTargetElement(Attributes = "hx-put," + FragmentAttributeName)] [HtmlTargetElement(Attributes = "hx-patch," + ActionAttributeName)] [HtmlTargetElement(Attributes = "hx-patch," + ControllerAttributeName)] @@ -83,8 +77,6 @@ namespace Ramstack.HtmxToolkit.TagHelpers; [HtmlTargetElement(Attributes = "hx-patch," + RouteAttributeName)] [HtmlTargetElement(Attributes = "hx-patch," + RouteValuesDictionaryName)] [HtmlTargetElement(Attributes = "hx-patch," + RouteValuesPrefix + "*")] -[HtmlTargetElement(Attributes = "hx-patch," + HostAttributeName)] -[HtmlTargetElement(Attributes = "hx-patch," + ProtocolAttributeName)] [HtmlTargetElement(Attributes = "hx-patch," + FragmentAttributeName)] [HtmlTargetElement(Attributes = "hx-delete," + ActionAttributeName)] [HtmlTargetElement(Attributes = "hx-delete," + ControllerAttributeName)] @@ -94,8 +86,6 @@ namespace Ramstack.HtmxToolkit.TagHelpers; [HtmlTargetElement(Attributes = "hx-delete," + RouteAttributeName)] [HtmlTargetElement(Attributes = "hx-delete," + RouteValuesDictionaryName)] [HtmlTargetElement(Attributes = "hx-delete," + RouteValuesPrefix + "*")] -[HtmlTargetElement(Attributes = "hx-delete," + HostAttributeName)] -[HtmlTargetElement(Attributes = "hx-delete," + ProtocolAttributeName)] [HtmlTargetElement(Attributes = "hx-delete," + FragmentAttributeName)] [HtmlTargetElement(Attributes = "hx-action," + ActionAttributeName)] [HtmlTargetElement(Attributes = "hx-action," + ControllerAttributeName)] @@ -105,8 +95,6 @@ namespace Ramstack.HtmxToolkit.TagHelpers; [HtmlTargetElement(Attributes = "hx-action," + RouteAttributeName)] [HtmlTargetElement(Attributes = "hx-action," + RouteValuesDictionaryName)] [HtmlTargetElement(Attributes = "hx-action," + RouteValuesPrefix + "*")] -[HtmlTargetElement(Attributes = "hx-action," + HostAttributeName)] -[HtmlTargetElement(Attributes = "hx-action," + ProtocolAttributeName)] [HtmlTargetElement(Attributes = "hx-action," + FragmentAttributeName)] [RequiresUnreferencedCode("Razor Page URL generation is not compatible with trimming.")] public sealed class HtmxUrlTagHelper(IUrlHelperFactory factory, IOptions options) : TagHelper @@ -117,8 +105,6 @@ public sealed class HtmxUrlTagHelper(IUrlHelperFactory factory, IOptions - /// Gets or sets the protocol for the URL, such as http or https. - /// - [HtmlAttributeName(ProtocolAttributeName)] - public string? Protocol { get; set; } - - /// - /// Gets or sets the host name. - /// - [HtmlAttributeName(HostAttributeName)] - public string? Host { get; set; } - /// /// Gets or sets the URL fragment name. /// @@ -272,8 +246,8 @@ public override Task ProcessAsync(TagHelperContext context, TagHelperOutput outp pageName: Page, pageHandler: PageHandler, values: routeValues, - protocol: Protocol, - host: Host, + protocol: null, + host: null, fragment: Fragment); } else if (routeLink) @@ -281,8 +255,8 @@ public override Task ProcessAsync(TagHelperContext context, TagHelperOutput outp url = generator.RouteUrl( routeName: Route, values: routeValues, - protocol: Protocol, - host: Host, + protocol: null, + host: null, fragment: Fragment); } else @@ -291,8 +265,8 @@ public override Task ProcessAsync(TagHelperContext context, TagHelperOutput outp action: Action, controller: Controller, values: routeValues, - protocol: Protocol, - host: Host, + protocol: null, + host: null, fragment: Fragment); }