Open mrpmorris opened 1 year ago
It's definitely something we've discussed on the team. For .NET 8 there isn't a way to trigger it dynamically so you will need to have it disabled if you can't rely on JS.
My personal preference would be to have a conservative mode that only enables streaming rendering if the request arrives with a certain cookie, and that cookie would be set by blazor.web.js
. So, the very first visit from any given user would not have streaming SSR, but if they have JS enabled, then all their subsequent requests would get it.
This could still go wrong if that user later disables JS, but there's no way for the server to know if that has happened so this is unavoidable.
@mkArtakMSFT I recommend we consider this as an enhancement for .NET 9.
Hi Steve
Thanks for your quick response.
I was under the (mis)understanding that this is how it worked. It's a shame, because I thought it would act as a kind of alternative to htmx without having to introduce multiple new endpoints on the servrer. A full progressive-enhancement approach by default, it would have been quite brilliant!
Do you think there might be a way to achieve this in .Net 8 with some kind of middleware to modify the requests and responses, or does adding this attribute cause a difference in code generation?
The server-side logic looks for StreamRenderingAttribute
, and that's the only thing that controls it. If streaming is determined to be enabled, then the response HTML comes out in a different shape that requires blazor.web.js
.
Theoretically you could put some middleware on the server that buffers the response and then somehow parses and rewrites the HTML to convert it back to a nonstreaming shape, but that sounds very difficult and fragile.
Thanks for contacting us.
We're moving this issue to the .NET 9 Planning
milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.
I almost had a solution but, unfortunately, the result of looking up StreamRendering is cached. https://source.dot.net/#Microsoft.AspNetCore.Components.Endpoints/Rendering/EndpointComponentState.cs,22
public class MyStreamRenderingAttribute : StreamRenderingAttribute
{
public MyStreamRenderingAttribute(bool enabled = true) : base(GetEnabled(enabled))
{
}
private static bool GetEnabled(bool enabled)
{
if (!enabled) return false;
var httpContext = new HttpContextAccessor().HttpContext;
bool result =
httpContext is not null
&& httpContext.Request.Cookies.TryGetValue("x-JSEnabled", out string? jsEnabled)
&& jsEnabled?.ToLowerInvariant() == "true";
return result;
}
}
Would it be acceptable to add an overload to the StreamRenderingAttribute
constructor to have the name of a static method to execute to get the value, or some other way of registering a way of programmatically determining it from Component+StreamRenderingAttribute, such as a global hook?
SomeGlobalThing.StreamRenderingHookOfSomeKind = static (IComponent component, StreamRenderingAttribute streamRendering) => streamRendering.Enabled && {SomeCodeOfMyOwn}
Then this approach would work, and we'd have progressive enhancement, which would be amazing!
@mrpmorris It's too late to add features like this to .NET 8, and we can make a better API for it in .NET 9. Sorry that's not ideal for you.
It's a shame, but it's my fault for not looking at .Net 8 earlier.
Thanks!
Using .NET 8 the best solution I can see at the moment is, have a cookie set by some JavaScript, then have two endpoints, one with StreamRenderingAttribute and one without for non JavaScript. The endpoint with StreamRenderingAttribute will check the presence of the cookie and if it doesn't exists it redirects to the non JavaScript endpoint.
You could put the JavaScript to add the cookie on a previous page. But if you don't have a previous page then the initial request will go to the non JavaScript endpoint which will contain the JavaScript to add the cookie for subsequent requests to use stream rendering.
Thanks for contacting us.
We're moving this issue to the .NET 9 Planning
milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.
Is this something I could contribute?
If so, could someone give me some guidance?
Is there an existing issue for this?
Describe the bug
UK Gov only allows javascript as an experience enhancement. All sites must work on browsers with JS disabled.
If I disable JS and run the new Blazor web app "Weather" page I just get an endless
Loading...
message.To fix this I have to remove
@attribute [StreamRendering(true)]
, but then I cannot make use of StreamRendering in the majority of browsers that have JS enabled.Could this please be fixed to have a fallback, so
StreamRendering
is only active iftrue
and JS is enabled?Expected Behavior
Running a
StreamRendering(true)
decorated page should not stop the page working in a browser with JS disabled.Steps To Reproduce
1: New Blazor web app 2: Include the sample pages 3: Disable JS in the browser 4: Run the app
Exceptions (if any)
No response
.NET Version
8.0.100-rc.2.23502.2
Anything else?
No response