Problem/Motivation
When using the HTMX native hx-boost attribute on the <body> tag, HTMX does replace the page contents, but
- Behaviors are not applied: #3560659: HTMX Drupal behaviors are not applied when swapped element is body
- You see all
ajax_page_statekeys passed along by the Ajax behavior in the updated URL history. This is supposed to be resolved once #3546105: Automatically manage _wrapper_format for HTMX requests and clean up ajax_page_state in urls is fixed.
I think this is a general problem that Drupal wraps the HTMX library to be an Ajax replacement in a too aggressive way. There are use cases outside of Drupal's Ajax system. For example, hx-boost is not something that Drupal Ajax would've been used for.
Steps to reproduce
- Add
hx-boost="true"attribute to the<body>tag, for example viatemplate_preprocess_html. - See that HTMX itself does the job, but you see the unexpected effects as listed above.
Proposed resolution
Within htmx-assets.js, there is the following event listener:
htmx.on('htmx:configRequest', ({ detail }) => {
const url = new URL(detail.path, document.location.href);
if (Drupal.url.isLocal(url.toString())) {
// Allow Drupal to return new JavaScript and CSS files to load without
// returning the ones already loaded.
// @see \Drupal\Core\StackMiddleWare\AjaxPageState
// @see \Drupal\Core\Theme\AjaxBasePageNegotiator
// @see \Drupal\Core\Asset\LibraryDependencyResolverInterface::getMinimalRepresentativeSubset()
// @see system_js_settings_alter()
const pageState = drupalSettings.ajaxPageState;
detail.parameters['ajax_page_state[theme]'] = pageState.theme;
detail.parameters['ajax_page_state[theme_token]'] = pageState.theme_token;
detail.parameters['ajax_page_state[libraries]'] = pageState.libraries;
}
});
It would be great if there is a convenient way to opt-out the manipulation of the request url.
There are also other things that need opt-out, for example attaching behaviors. There might be situations where a developer needs to apply very specific attachment of behaviors.
Comments
Comment #2
mxh commentedComment #3
mxh commentedComment #4
mxh commentedComment #5
mxh commentedComment #6
mxh commentedWhen digging deeper I found another problem: #3560659: HTMX Drupal behaviors are not applied when swapped element is body
Comment #7
nod_Could you try #3546105: Automatically manage _wrapper_format for HTMX requests and clean up ajax_page_state in urls, this should resolve the ajax_page_state ending up in the browser history.
We need to wrap the library to some extend because of a few things:
ajax_page_state[libraries]ajax_page_state[theme]andajax_page_state[theme_token]So this is the kind of expectations we need to define, and I'm very glad to see other people using this so we can discuss :)
This is the slippery slope that granted us all the features of the Ajax framework, very powerful but complex and underused. I wouldn't want to add a way to have "Drupal-wrapped" htmx and "regular" htmx. I think we can make it so our htmx implementation does not break the expectations of regular htmx in most cases.
Comment #8
nod_Also curious as to why you need the head support plugin :)
Comment #9
fathershawnI had the same question as #8 when I read the issue summary :)
Comment #10
mxh commentedComment #11
mxh commentedI just realized today that HTMX 2.x should not require this plugin anymore, so I removed it from the IS. It seems if core/drupal.htmx would work properly with the
<body>tag and would not show the ajax-related URL query parameters in the URL history, thenhx-boostcould work as expected.Comment #12
mxh commentedComment #13
mxh commentedYes it resolves the flooding of the ajax_page_state arguments in the URL history. But has another effect that it only renders the main page contents. Left my findings in that issue as well.
Comment #14
mxh commentedI tried #3546105: Automatically manage _wrapper_format for HTMX requests and clean up ajax_page_state in urls once more and can confirm it's getting this issue forward. Updated the IS at the two bullet points identified for this. I could maybe close this one in favor of #3560659: HTMX Drupal behaviors are not applied when swapped element is body. However I have seen some problems after attached behaviors, where I'm currently not sure whether they need to be addressed as well. It seems some behavior implementations work well whereas other don't.
Comment #15
quietone commentedComment #16
longwaveNow that #3546105: Automatically manage _wrapper_format for HTMX requests and clean up ajax_page_state in urls landed and the IS only links one other issue, is this one still needed, or should we just close this in favour of #3560659: HTMX Drupal behaviors are not applied when swapped element is body? It's not clear that there is anything else specific left to solve here.
Comment #17
nod_The point left seems to be about behaviors not working nice with a boost page navigation.
We have many behaviors that do not detach cleanly, this might be one of the reasons why it's not working very well.
Comment #18
mxh commentedExactly. Could create an issue regarding these problems, then close this maybe?