Blazor .NET 8 introduces the new SSR for razor pages of "static" character. This is nice for login, status page or other non-interactive pages. On the downside it seems that having pure SSR pages forces the layouts to be non-interactive as well. In other words, I cannot have C# frontend code (interaction) on the layouts (MainLayout.razor etc). If I want that, I neeed to move both the MainLayout.razor AND the Routes.razor to the Client project and set their rendermode to InteractiveAuto. However, then I cannot render pure SSR pages any more, since routing is taken over completely by the client logic (Blazor Server/WASM)
Is there a way to combine the best of both worlds? I'd like to have a few static pages rendered only by SSR, while most of the other pages require an interactive layout with widgets etc.
Essentially the Router should always be rendered server-side, while the layout's rendermode should depend on the scenario:
Is this possible?
I do no have points to allow a comment so I have had to add another answer to clarify a couple of things for @epoch and the OP.
As far as I know (currently), if you want to have mixed modes (SSR and WASM, SSR, WASM and Server), then auto per component/page project (currently) is most likely the best way to go, with the router on the server side. Again, as far as I understand, route discovery is determined by AddAdditionalAssemblies(typeof(Client._Imports).Assembly) in the server program.cs file and from the router, either on the server or client.
Currently (it may change, or it may be bugs, I do not know), if you have the router on the client and, say, a server interactive page on the server, going from the client to server runs the server component/page; it displays, then immediately goes to the 'page not found' text. Ironically, having the server component on the client works fine.
Other quirks: when you have mixed interactive components, if there is a WebSocket open to a server page/component and you navigate to a client component (that is cached on the client and has run on the client), if the WebSocket is open, the interactive WebAssembly component will run as a server component unless the prerender for the WebAssembly component has been set to false.
Regarding my first post, as it was probably not clear and you should know if you go that route, global WASM with SSR (the Blazor template/code) is that when I pointed out going from WASM to SSR and back to WASM, the call goes to the server and then runs on the client, I should have said RE-RUNS on the client, i.e., the client-side program.cs is re-run despite it already being on run and cached. I have not checked if this is just a debug runtime behavior (or bug) or happens after publishing; I suspect it is both.
This behavior may be fine for some apps/sites where there is not a lot of transition from SSR to WASM. Another thing to check, if going this route, would be client-side local browser session cache (if you use it for, say, storing validation rules); I have not checked yet, would this get wiped out or remain as you have not changed tabs?
My final thoughts and just my opinions based on my usages of Blazor to date: Blazor WASM with Server API works great (excluding initial download); the new auto per component works well if you embrace the quirks (bugs?) and you do not need the app to work (for prolonged periods) without the internet. If you embrace the new way, just remember that any component running on the client that you may want prerendering will require a couple of extra steps, i.e., a shared interface that you can register on both the client and server to provide the concrete implementations of code for when the code first runs on the server and then subsequently runs on the client (plenty of posts on that). And the code if you want to share/download the prerendered state (again lots of posts on that as well). Or turn off prerendering for the component.
Sorry for the additional post, but hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With