Blazor
A Blazor component renders a page through RazorComponentResult. The component is a plain one,
with no @page, and gets the page through a parameter named Content:
@* Components/ArticlePage.razor *@
@using MySite.Models
<PageTitle>@Content.Name</PageTitle>
<h1>@Content.Name</h1>
@((MarkupString)Content.Body)
<LikeButton ArticleId="@Content.Id" @rendermode="InteractiveServer" />
@code {
[Parameter] public IArticle Content { get; set; } = default!;
}using Microsoft.AspNetCore.Http.HttpResults; // RazorComponentResult
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
builder.AddRelatudeCMS()
.AddRendering(o => o
.RenderResult<IArticle>((http, article) => new RazorComponentResult<ArticlePage>(new { Content = article })));
app.UseAntiforgery(); // MapRazorComponents needs it, even for static pages
app.MapRazorComponents<App>().AddInteractiveServerRenderMode();
app.MapRelatudeCMS();Two rules keep this working:
- Render content pages statically, with interactive islands inside them. The page is found from
the request, which exists only while the component renders on the server. Put interactive parts in
child components with their own
@rendermode, likeLikeButtonabove. - Never pass a node into an interactive component. Its parameters are serialized to the browser
or the circuit, and a node's relations would pull in every related node. Pass an id or a small
projection. Once the component runs interactively there is no request, so it reads what it needs
through
IRelatudeDBAccessoror a service of its own, not throughRelatudeCmsContext.
RazorComponentResult renders the component as a whole document, outside the host's App.razor,
Routes.razor and layout. The component, or a layout component it wraps itself in, must produce
the <html> and <head> it needs, and the Blazor script when it has interactive parts.
A @page "/" in the host's own Blazor pages hides the CMS home page, since a literal route beats
the content routes' catch-all. So does any @page whose route matches the URL of a page.