Config tag helper
htmx 4 reads its settings from a <meta name="htmx-config"> tag. Writing that JSON by hand is error prone, so HtmxConfigMetaTagHelper lets you set each option as a typed attribute and serializes the content for you. Reach for it whenever you change a default (swap style, timeout, noSwap statuses, morph options) or want the antiforgery token embedded.
Enable it with @addTagHelper *, Htmx.TagHelpers in _ViewImports.cshtml, then put the tag in your layout <head> before the htmx script:
<meta name="htmx-config" includeAspNetAntiforgeryToken="true" defaultSwap="outerHTML" transitions="true" noSwap="@(new object[] { 204, 304, 422 })" />which renders roughly as:
<meta name="htmx-config" content='{"defaultSwap":"outerHTML","transitions":true,"noSwap":[204,304,422],"antiForgery":{...}}' />Unset attributes are not serialized, so htmx’s own defaults apply.
Typed value examples
Section titled “Typed value examples”<meta name="htmx-config" logAll="false" history="true" mode="same-origin" defaultTimeout="45000" defaultSettleDelay="5" indicatorClass="loading-dot" requestClass="is-loading" morphIgnore="@(new[] { "data-htmx-powered", "data-keep" })" morphSkip="[data-skip]" morphSkipChildren="[data-skip-children]" morphScanLimit="7" noSwap="@(new object[] { 204, 304, 422, "5xx" })" inlineScriptNonce="@nonce" />bool?,int?andstring?attributes are omitted when not set.morphIgnoretakes astring[];noSwaptakesobject[](status numbers and/or status-pattern strings).historyis typed as a string ("true","false"or a mode), sohistory="true"reads back as"true"inhtmx.config.includeAspNetAntiforgeryToken="true"(C#IncludeAntiForgery) writes anantiForgeryobject with the header name, form field name and request token. See Antiforgery.
Page-scoped config with a layout section
Section titled “Page-scoped config with a layout section”Only one htmx-config meta may exist on a page. To let an individual page replace the global config, make the layout render a section when it is defined:
@* _Layout.cshtml *@@if (IsSectionDefined("HtmxConfig")){ @await RenderSectionAsync("HtmxConfig")}else{ <meta name="htmx-config" includeAspNetAntiforgeryToken="true" indicatorClass="htmx-indicator" />}@* Config.cshtml *@@section HtmxConfig { <meta name="htmx-config" includeAspNetAntiforgeryToken="true" defaultSwap="beforeend" defaultTimeout="45000" noSwap="@(new object[] { 204, 304, 422 })" implicitInheritance="false" />}Attribute reference
Section titled “Attribute reference”| Attribute | Type | htmx 4 default |
|---|---|---|
logAll |
bool | false |
prefix |
string | "data-hx-" |
metaCharacter |
string | : |
transitions |
bool | false |
history |
string / bool | true |
mode |
string | "same-origin" |
defaultSwap |
string | "innerHTML" |
allowEmptySwapAfterOOB |
bool | false |
defaultFocusScroll |
bool | false |
defaultSettleDelay |
int (ms) | 1 |
indicatorClass |
string | "htmx-indicator" |
requestClass |
string | "htmx-request" |
includeIndicatorCSS |
bool | true |
defaultTimeout |
int (ms) | 60000 |
extensions |
string | "" |
morphIgnore |
string[] | ["data-htmx-powered"] |
morphSkip |
string (selector) | "[hx-morph-skip]" |
morphSkipChildren |
string (selector) | "[hx-morph-skip-children]" |
morphScanLimit |
int | 10 |
noSwap |
object[] (numbers / status patterns) | [204, 304] |
implicitInheritance |
bool | false |
inlineScriptNonce |
string | none |
includeAspNetAntiforgeryToken |
bool | false (library-specific; see Antiforgery) |
Tag helper members
Section titled “Tag helper members”HtmxConfigMetaTagHelper exposes one property per attribute: LogAll, Prefix, MetaCharacter, Transitions, History, Mode, DefaultSwap, AllowEmptySwapAfterOOB, DefaultFocusScroll, DefaultSettleDelay, IndicatorClass, RequestClass, IncludeIndicatorCSS, DefaultTimeout, Extensions, MorphIgnore, MorphScanLimit, MorphSkip, MorphSkipChildren, NoSwap, ImplicitInheritance, InlineScriptNonce, IncludeAntiForgery, plus the injected ViewContext and the overridden Process(...).
Renamed or removed from htmx 2
Section titled “Renamed or removed from htmx 2”Use defaultSwap (was defaultSwapStyle), transitions (globalViewTransitions), history (historyEnabled), includeIndicatorCSS (includeIndicatorStyles), defaultTimeout (timeout). Many htmx 2 keys (historyCacheSize, selfRequestsOnly, withCredentials, allowEval, inlineStyleNonce, …) no longer exist; see the htmx 4 reference.
Effect of config on server code
Section titled “Effect of config on server code”defaultSwap and noSwap change what the client does with your responses. By default htmx 4 swaps 4xx/5xx responses; only 204 and 304 are skipped. Add statuses to noSwap (or use hx-status) to opt out.
Examples you will feel on the server:
defaultSwap="beforeend"makes responses to elements withouthx-swapappend instead of replace.noSwapincluding422means a validation fragment returned with422is not shown. Leave it out to render validation errors (htmx 4 swaps them by default).implicitInheritance="true"restores htmx 2-style attribute inheritance; keep itfalseto use explicit:inherited(see URL tag helper).prefixis additive tohx-; a custom value replaces the secondarydata-hx-prefix. The tag helpers recognize bothhx-anddata-hx-spellings.
See the live demo: run dotnet run --project samples/Htmx4.Sample and open /Config (source). It reads htmx.config back so you can see what the browser received.
Related: htmx 4 reference: configuration, Antiforgery, Partials and morph.
From the blog: JSON in HTML Attributes with ASP.NET Core TagHelpers explains the htmx-config meta tag helper.