egil / Htmxor

Supercharges Blazor static server side rendering (SSR) by seamlessly integrating the Htmx.org frontend library.
MIT License
124 stars 13 forks source link

Enable Htmxor and standard Blazor to co-exsist #57

Open egil opened 4 months ago

egil commented 4 months ago

Ideally, users should be able to add Htmxor to their Blazor apps, and start taking advantage of it in some parts of the solution, and keep using other render modes in other parts.

There is a few big questions that needs answering to understand if this is possible:

  1. Can htmx and blazor.web.js coexist without treading on each other's feet?

  2. Can we choose the rendering pipeline per request - basically implement a request handler that forwards to either the native endpoint handler or htmxor's.

  3. Will that also enable the switching between the three render modes Blazor 8 comes with out of the box?

  4. Do we need to explicitly introduce a custom render mode, to ensure that Blazor's standard rendering logic does not attempt to render components that leverage htmx and htmxor or is that unnecessary?

Resources:

@khalidabuhakmeh's article hints of co-exsistance being possible: https://khalidabuhakmeh.com/how-to-use-blazor-server-rendered-components-with-htmx

Inspired by the discussion https://github.com/egil/Htmxor/discussions/42.

garrettlondon1 commented 3 months ago

I think aspnetcore team needs more persuasion from the community that blazor.web.js needs to work normally and not have enhanced navigation blow everything up from js/htmx perspective.

egil commented 3 months ago

I think aspnetcore team needs more persuasion from the community that blazor.web.js needs to work normally and not have enhanced navigation blow everything up from js/htmx perspective.

@garrettlondon1 I think that can be disabled. There are some hooks for overriding the behavior, so it should be possible to disable on pages htmx should control and enable on others thst blazor handles.

garrettlondon1 commented 3 months ago

I think aspnetcore team needs more persuasion from the community that blazor.web.js needs to work normally and not have enhanced navigation blow everything up from js/htmx perspective.

@garrettlondon1 I think that can be disabled. There are some hooks for overriding the behavior, so it should be possible to disable on pages htmx should control and enable on others thst blazor handles.

Yes you can use custom PageScript component but the problem with disabling enhanced navigation is that a brand new websocket will open, and circuit will reconnect.

If you could turn off enhanced navigation, and keep the same circuit, this wouldn't be an issue

egil commented 3 months ago

Yes you can use custom PageScript component but the problem with disabling enhanced navigation is that a brand new websocket will open, and circuit will reconnect.

If you could turn off enhanced navigation, and keep the same circuit, this wouldn't be an issue

My understanding is that enhanced page nav and enhanced forms is only in play with static server side rendered pages. SignalR is not used on those pages.

Htmxor is only a replacement for static ssr.

garrettlondon1 commented 3 months ago

Yes you can use custom PageScript component but the problem with disabling enhanced navigation is that a brand new websocket will open, and circuit will reconnect.

If you could turn off enhanced navigation, and keep the same circuit, this wouldn't be an issue

My understanding is that enhanced page nav and enhanced forms is only in play with static server side rendered pages. SignalR is not used on those pages.

Htmxor is only a replacement for static ssr.

Enhanced navigation plays a role in other render modes as well

The ideal scenario is to take advantage of partials/htmx plus InteractiveServer if needed for advanced interactions.

Both of those currently don't play well together

egil commented 3 months ago

Enhanced navigation plays a role in other render modes as well

I am not sure how? Yes, if you are on a

But navigation between wasm pages or between InteractiveServer pages should not use enh-nav. Why would it?

The ideal scenario is to take advantage of partials/htmx plus InteractiveServer if needed for advanced interactions.

Why would you want to mix InteractiveServer with htmx(or)? InteractiveServer already has a SignalR connection open and is a more straight forward way of achieving the same that htmx(or) has to work harder for.

In my mind, htmxor is a replacement for SSR, and it will enable you to rely less on Wasm or InteractiveServer, because it is more versatile compared to Blazor SSR.

Both of those currently don't play well together

I am not planning to attempt to make Wasm or InteractiveServer work well together with Htmxor on the same page.

garrettlondon1 commented 3 months ago

InteractiveServer I find is amazing to use instead of subscribing to web socket from client side

I'd say I use it for about 10% of the application in "Interactive Islands" - full SSR with blazor.web.js

If I ported to pure HTMX, it'd be thousands of more lines of vanilla JS in my codebase. I still don't want to use InteractiveServer for the rest of the app, however.

This initiative is awesome and looking forward to it.

Best Garrett

egil commented 3 months ago

InteractiveServer I find is amazing to use instead of subscribing to web socket from client side

Exactly, if you want that level of interactivity and would get that using web sockets, yeah, might as well use interactiveserver and get that to do the heavy liften. SignalR is just websockets wrapped in a nicer api.

Htmx and htmxor is not a replacement for a fully interactive "interactiveserver" app in my mind. htmxor allows you to create an nice interactive experience WITHOUT having a statefull app. Stateless apps are much less complex to maintain.

garrettlondon1 commented 1 month ago

Question on this @egil, regarding stateful nature of Blazor Server.

When you load a page, and websocket initializes, it connects to server A. Currently, Blazor Server requires sticky sessions because it reuses the circuit across HTTP requests?

If enhanced navigation is disabled and circuit is re-established every time page is loaded, why couldn't you turn off ARRAffinity token and sticky sessions? Shouldn't the websocket be able to connect to any server it wants to?

The websocket state is stateful, yes, but the application still operates in a distributed manner, where the load balancer does not need to keep track of sessions or ARRAffinity tokens

Correct me if I'm wrong.

I think the benefit of bringing Htmxor and InteractiveServer blazor in one package will be huge

egil commented 3 weeks ago

@garrettlondon1 my idea is that htmxor would introduce what is a new render mode. Blazor comes with four render modes out of the box:

My thinking is that Htmxor would introduce its own render mode, e.g. Htmxor, that users can use on individual pages in their apps. Right now, Blazor allows you to have some pages that use Static Server and some that use the interactive modes in the same app.

The key is that a page (component) only uses one render mode at the time, so if e.g., Interactive Server is active, neither Htmxor nor any of the other modes will be used on the page.

Hope this explains a little better what I am trying to do.