leotaku / tower-livereload

Tower middleware to automatically reload your web browser during development
Apache License 2.0
62 stars 7 forks source link

Support to dicate where injected snippet is placed. #7

Open pbouzakis opened 10 months ago

pbouzakis commented 10 months ago

Currently, livereload is appending itself to the end of the HTML response which means its outside the outer HTML tag.

Is there any to specify a placeholder of where it can inject the snippet. Example - it would be great to set it inside the head tag.

Here's a screenshot of what my current HTML output looks

Screenshot 2023-11-22 at 8 37 08 PM
leotaku commented 10 months ago

This is not currently supported and also not really planned. We deliberately do not use any HTML parser/templating library/... to keep complexity and dependency count low. Do you experience any problems with the placement of the script tag, or is this purely an aesthetic preference?

pbouzakis commented 10 months ago

When using htmx, if you use the history push state feature, when the library attempts to restore a previous state of the page they will re-render anything in the body (by default), this means that any script tag in the body will be parsed again. So when I navigate back and forth, the polling causes the server to stop responding.

I am able to configure htmx to restore a different DOM element, but it does mean by default tower livereload placement of its script is problematic.

May I suggest an alternative that also keeps the complexity low since this seems to be a goal of the library.

What if you could pass a flag to disable injecting the script, leaving the application in charge of placing the snippet? This also means you will need to expose the snippet HTML so that the app code can reuse the same js script and place where they prefer.

leotaku commented 10 months ago

Ah, I think users previously have experienced a similar issue in #2. My comment in #3 shows an example of how to fix it with HTMX specifically. I am only somewhat familiar with the internals of HTMX, so there might be a reason this does not work with the "history push" functionality. However, in my limited testing, reloading keeps working even when I navigate back and forth a bunch of times.

pbouzakis commented 10 months ago

Yes I already have a solution for not adding livereload to requests not triggered by htmx.

This is a different issue. You have to leverage the hx-push-url attribute.

Any thoughts on allowing app code to turn off the auto-injection and exposing the snippet? Seems like it would be the simplest solution and provide app devs with more control.

leotaku commented 10 months ago

Yes I already have a solution for not adding livereload to requests not triggered by htmx.

I assume you mean "not adding livereload to requests not triggered by htmx"?

This is a different issue. You have to leverage the hx-push-url attribute.

I've tried to reproduce this issue on my end, but I'm not experiencing the effects you describe. When I use hx-push-url, tower-livereload will connect to the poll endpoint multiple times, which is probably undesirable and should be fixed, but for me this does not result in the server stopping to respond. If you could provide me with a minimal reproducible example that would be of great help.

Any thoughts on allowing app code to turn off the auto-injection and exposing the snippet? Seems like it would be the simplest solution and provide app devs with more control.

Not a huge fan of the idea of exposing the JS snippet. Maybe exposing the poll/back-up URLs so that app developers can write their own reload logic would be a more elegant solution. However, at that point adding a very simplistic </head> scanner might be more beneficial for more users. I will have to think about it.

edezhic commented 9 months ago

While the fix in #3 worked for me it took a while to understand at which point things go wrong and that the issue is related to tower-livereload. Would be nice to make this lib compatible by default or to do as @pbouzakis suggested, or maybe mention this detail in readme idk.

thallada commented 9 months ago

I would like to report that I am also having an issue with the placement of the livereload snippet and it's interaction with HTMX.

I do not use hx-push-url attribute directly. Instead, I have set hx-boost on my <body> element which I assume uses hx-push-url under the hood when any link is clicked.

If I click on a link, press my browser back button, then click the link again. After about 7-9 cycles of that, the link (and any other link on the page) doesn't work anymore. The request never hits the backend.

I think it might be because the "long-poll" is made again every time I go back:

image

It specifically only happens if I use the browser back button, navigating through pages via link clicks on the pages still works after 9 clicks (and it doesn't make an extra long-poll request in the network log).

Also, this sounds very similar to the same issue this commenter had with forms: https://github.com/leotaku/tower-livereload/issues/2#issuecomment-1806729931

I put the liveReload middleware at the end of the routes, it working fine. But after I click my button 7 times to do POST request with htmx, the button stopped working.

I am using HTMX with tower-livereload in an axum server. I only enable livereload in debug mode.

I added the not_htmx_predicate from #3 which does remove the livereload snippet from HTMX responses, however it did not fix the issue of links not loading after 8 redirects.

All links work okay after the 8th link if I remove tower-livereload. Maybe this is more of an HTMX issue, but I think it would be nice to be able to configure where the snippet goes if it is in fact an issue with it's placement in the body element.