Skip to content

Make RenderTreeBuilder.AddComponentRenderMode's renderMode parameter nullable #51170

@halter73

Description

@halter73

Background and Motivation

To support disabling interactivity on a per-page basis with the help of @rendermode="null" for use in our project templates when generating a Blazor app with individual auth and global interactivity. See #51134.

Proposed API

namespace Microsoft.AspNetCore.Components.Rendering;

public sealed class RenderTreeBuilder : IDisposable
{
-    public void AddComponentRenderMode(IComponentRenderMode renderMode);
+    public void AddComponentRenderMode(IComponentRenderMode? renderMode);
}

Usage Examples

App.razor

<!DOCTYPE html>
<html lang="en">

<head>
    <!-- ... -->
    <HeadOutlet @rendermode="@RenderModeForPage" />
</head>

<body>
    <Routes @rendermode="@RenderModeForPage" />
    <script src="_framework/blazor.web.js"></script>
</body>

</html>

@code {
    [CascadingParameter] HttpContext HttpContext { get; set; } = default!;

    IComponentRenderMode? RenderModeForPage => HttpContext.Request.Path.StartsWithSegments("/Account")
        ? null
        : RenderMode.InteractiveServer;
}

Alternative Designs

We could add a new RenderMode.StaticServer to mean the same thing that null does with this proposal.

We could also look at other public API that accept a non-nullable render mode like RenderModeAttribute:

namespace Microsoft.AspNetCore.Components;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public abstract class RenderModeAttribute : Attribute
{
-    public abstract IComponentRenderMode Mode { get; }
+    public abstract IComponentRenderMode? Mode { get; }
}

This could be useful for forcing a component to only render statically.

Risks

It's risky making API changes after RC2 because that means we have no opportunity to change the API again based on customer feedback. I think this risk is minimized because it's only a change to the nullability annotation and it makes it more relaxed.

Perhaps the bigger risk is that it locks us into null representing a non-interactive renter mode. This is already the case internally, but that could be confusing if we wanted to add something like RenderMode.StaticServer in the future to represent the same thing. At least that could still work though.

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-blazorIncludes: Blazor, Razor Components

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions