https://htmx.org logo
Join Discord
Powered by
# htmx-general
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:08 AM
    what is the current behavior of html now? i am not familiar with out of bounds but i think other parts of htmx would just ignore it
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:09 AM
    both the html and head
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:10 AM
    I guess the way i see it is that if you can solve something with server side/static generation then that probably should not be tried to be solved by htmx
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:11 AM
    merging a head would be an example of that. Define your full heads, compose them if you need to, generate them. htmx can replace full heads, done.
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:11 AM
    (or can implement that. i am not sure what the current status of head handling is)
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:12 AM
    "magic" is too generic and broad, I would characterize it as hidden, not expressive, not explicit (changing behavior based on html being present or not)
  • b

    brainy-ice-92385

    10/09/2022, 1:29 AM
    Not disagreeing with anything you're saying. But on this point, the thing is that JavaScript will re-execute if you place a script tag in the DOM, even if it's verbatim what another one was. So I think that's the issue that starts one considering more complex solutions. But again I don't disagree with you (tho i hold a different preference)
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:48 AM
    is this script on the body or in the head? (I dont think i have the full context of what is being discussed)
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:49 AM
    ah i think i see. if a merge is not performed and the head is replaced as a whole all the scripts will rerun even those that had previously run
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:50 AM
    and i guess if the script is brought to something in the body that can lead to other similar or worse issues
  • c

    cuddly-keyboard-70746

    10/09/2022, 1:53 AM
    uhm... If i got that right then... perhaps I would advocate for more "magic". My mind is going towards something react like, where only the head diff would be added/executed. dont listen to me, i may just be tired/not have the right mindset rn.
  • c

    cuddly-keyboard-70746

    10/09/2022, 4:20 AM
    idk. perhaps just pay the price upfront (defer async etc) and forget it. for libs and stuff
  • c

    cuddly-keyboard-70746

    10/09/2022, 4:20 AM
    then the js is already loaded ready to be used
  • c

    cuddly-keyboard-70746

    10/09/2022, 4:21 AM
    maybe it is not a perfect answer (for every use case) but at the very least it seems to me that would be the htmx way (at least so far)
  • b

    brainy-ice-92385

    10/09/2022, 7:20 AM
    I think you're just catching up to the conversation. Someone requested this feature and that's why it's being discussed 🙂 You hit all the important bits.
  • s

    square-oyster-36295

    10/09/2022, 1:18 PM
    Hey @mysterious-toddler-20573, @brainy-ice-92385 and @cuddly-keyboard-70746 - thanks for your conversation yesterday, I read it all. I did some practical tests and Turbo has the most reliable and functional merging of in the context of , and tags. The implementation can be seen in the
    mergeHead
    function and related functions - https://github.com/hotwired/turbo/blob/4e8ba783419cc01c0aa42d01cbca313e28b35016/src/core/drive/page_renderer.ts#L62 Their implementation even manages to perfectly merge, for example, in the case of the DEV mode of web development in Astro, which inserts inline or tags into the in addition to external links to JS/CSS. Everything is inserted and interpreted correctly. Duplicate content is not inserted there when browsing the web. At the same time, what happens is that the and tags are not removed, only added, because that would cause flickering and broken content when replaced. Unlike HTMX, Turbo has a very limited use, but it can merge headers flawlessly. By the way, I've mentioned it somewhere before, but we're looking to use HTMX by having a headless CMS and using Astro for the frontend. We use it for projects either in SSG mode, or for more dynamic projects with filter forms, in SSR mode. We generate 99% of HTML code only in SSR mode. In any case, we no longer want to strive for an isomorphic code, which is why we choose the Astro + HTMX way. All pages and their URLs return complete HTML. Astro uses Vite and generates in the only the CSS and JS needed on the page. The production build includes a couple of external JS/CSS chunks in the related to current page. We also have little inline JS/CSS in selected components.
  • s

    square-oyster-36295

    10/09/2022, 1:19 PM
    We currently have 2 issues with Astro using HTMX: * merging doesn't work, so HTMX is unusable for web navigation implementations that don't have just global stylesheet and global JavaScripts * At the same time, it is not possible to implement this simple scenario in the navigation area: "After clicking on any link in the menu, load the URL with XHR and from the loaded HTML, replace the content of elements #content and #sidebar and at the same time merge ". It is currently not possible to select multiple target elements to replace. OOB tries to replace this need, however, it requires a custom backend that returns OOB elements at the TOP level, which is also unusable for our use-cases. If HTMX is natively able to perform these scenarios as well, it will be fantastic and usable for other types of projects for which developers today are forced to use Unpoly, HotWire/Turbo or other libraries. At the same time, OOB rotates responsibility for this scenario. When I think about a specific link, at that moment, I know what should happen after clicking and which content I would like to replace, therefore I would like to include the selectors of the replaced elements in the attribute, not control it from the backend (HTML markup with OOB attributes). HTMX and its data attributes are now only designed to replace a single element, especially in the area of hx-target and hx-select attributes. Maybe replacing multiple elements could be implemented using hyperscript, but it would probably be weird. I think this functionality should be a native part of HTMX. So that it is not necessary to interfere with the behavior of hx-target and hx-select, perhaps it would be possible to add an attribute, e.g. hx-replace, where it would be possible to list more selectors for simple replacement in HTML? Do you know any disadvantages or risks of this solution?
  • s

    square-oyster-36295

    10/09/2022, 1:34 PM
    Alternatively, I can think of a solution where it would be possible to optionally indicate the method of swapping by which the given element is to be explicitly replaced. Example:
    <a href="/" hx-replace="#content,#sidebar:morphdom,#list:beforeend">
    ... so #content will be replaced by default swapping method, #sidebar by morphdom extension and #list by beforeend. This nifty functionality would solve many, many useful scenarios.
  • m

    mysterious-toddler-20573

    10/09/2022, 2:38 PM
    I think the code that I have above will do the head merge in the same manner, not as object oriented and more direct, but it does handle both linked as well as inline scripts, css, etc. It does remove head elements no longer present, and htmx's focus on HTML fragments, rather than complete pages, introduces another wrinkle that we need to think about. Another aspect to consider is the history cache, which is one reason why I'm leaning towards integrating this into htmx, rather than as an extension. For the swapping issue, this seems like a perfect place to use an extension, maybe
    multi-swap
    ?
    Copy code
    html
    <button hx-get="/whatever" hx-ext="multi-swap" hx-swap="multi: #foo:innerHTML, #bar:outerHTML">
      Multi-Swap It
    </button>
    Once we prove it with an extension, I could see moving this into core as well.
  • m

    mysterious-toddler-20573

    10/09/2022, 2:40 PM
    Note that we do have hx-select-oob, which might also be useful here: https://htmx.org/attributes/hx-select-oob/
  • s

    square-oyster-36295

    10/09/2022, 5:25 PM
    @mysterious-toddler-20573 - Thank you for merge-head-scratch.html. I looked into it and it looks fine, but as you have in code comment
    ability to avoid being removed?
    , it is really desirable to be able to disable removing. Removing style/link tags can trigger content flickering, so it is better to not removing them in some scenarios.
  • s

    square-oyster-36295

    10/09/2022, 5:28 PM
    Also it's great idea to implement the requested functionality as another swap extension!
  • s

    square-oyster-36295

    10/09/2022, 5:35 PM
    JavaScript is not my forte, but I will try to develop this extension 🙂
  • b

    brainy-ice-92385

    10/09/2022, 6:49 PM
    I came to like 1cg's idea of marking head elements as "to preserve". If you're able to do that, e.g.:
    <script src="base.js" hx-preserve></script>
    Then L47 here you should just be able to add a guard like
    if (! currentHeadChild.hasAttribute('hx-preserve')) { ... do the removal ...}
  • s

    square-oyster-36295

    10/09/2022, 6:53 PM
    @brainy-ice-92385 - You're right, but I won't be able to add
    hx-preserve
    to these tags because they are generated by Astro/Vite. However, it should be easy to write a piece of your own JS code that would add
    hx-preserve
    in the browser. But the option to disable tag removal would be simpler.
  • b

    brainy-ice-92385

    10/09/2022, 6:57 PM
    That makes sense. The turbo code you sent seems to only remove some elements it calls "provisional" do you know what that distinction is?
  • s

    square-oyster-36295

    10/09/2022, 6:58 PM
    @mysterious-toddler-20573 - I wrote part of multi-swap extension , but now I don't know how to call swapping from htmx. See my TODO in the code (and ignore my attempt with swap()).
    Copy code
    javascript
    htmx.defineExtension('multi-swap', {
        isInlineSwap: function (swapStyle) {
            return swapStyle.indexOf('multi:') === 0;
        },
        handleSwap: function (swapStyle, target, fragment, settleInfo) {
            if (swapStyle.indexOf('multi:') === 0) {
                var elements = {};
                var elementsSplit = swapStyle.replace(/^multi\s*:\s*/, '').split(/\s*,\s*/);
    
                elementsSplit.map(function (element) {
                    var elementSplit = element.split(/\s*:\s*/);
                    if (elementSplit.length == 2) {
                        elements[elementSplit[0]] = elementSplit[1];
                    } else if (elementSplit.length == 1) {
                        elements[elementSplit[0]] = "innerHTML";
                    }
                });
    
                for (var elementSelector in elements) {
                    var elementSwapStyle = elements[elementSelector];
                    // TODO: HOW TO CALL SWAP?
                    // swap(elementSwapStyle, elementSelector, target, fragment, settleInfo);
                }
            }
        }
    });
  • s

    square-oyster-36295

    10/09/2022, 7:05 PM
    Btw,
    hx-swap
    attribute must not contain spaces, otherwise only e.g. "multi:" will be passed to the
    handleSwap
    method. Below is an example. For this , latest
    for
    cycle in the code contains parsed elements and it's swap styles from
    hx-swap
    , but now I don't know how to call swapping of these elements. If you don't have time to advise me, I will try to understand from the htmx.js code tomorrow how to implement it.
    Copy code
    html
    <a href="/contact" hx-ext="multi-swap" hx-swap="multi:#content:innerHTML,.exampleWithoutSwapStyle,#menu:outerHTML">Contact</a>
  • b

    brainy-ice-92385

    10/09/2022, 7:06 PM
    I think calling swap may not be possible from an extension in the current build
  • s

    square-oyster-36295

    10/09/2022, 7:08 PM
    @brainy-ice-92385 - Yes, it looks that is only internal method. I looked also into SSE (https://unpkg.com/htmx.org@1.8.0/dist/ext/sse.js) for inspiration and I saw usage of init() method to get apiRef. There is available
    selectAndSwap()
    method, but I don't know if is this method usable in this case.
1...849850851...1146Latest