Statiq.Framework
Statiq.Framework copied to clipboard
Razor Component Support?
Hi, I was just wondering, is it possible to render Razor Components (which are normally used with Blazor) within a cshtml file? There is a component Tag helper which you can set to static for rendering, although I couldn't get it to work
I tried adding something like this randomly to the basic example under Statiq.Web
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<component type="typeof(RazorClassLibrary1.Component1)" render-mode="Static" />
but just ended up with a
[ERRO] Archives/PostProcess » ExecuteSwitch » RenderContentPostProcessTemplates » ExecuteIf » ExecuteIf » RenderRazor » [D:/Temp/13/1/Statiq.Web/examples/Statiq.Web.Examples/input/archives/simple-archive.cshtml => archives/simple-archive.html] Invalid URI: The format of the URI could not be determined.
In theory Razor component support should be possible since we're using the "official" Razor engine with all the bells and whistles. That said, they're probably enabled via an additional Razor phase that will need to be added.
The error you got is interesting though, I wouldn't have expected to see any error if the component tag helper wasn't available. The fact you're getting some kind of error might mean components are better supported than I would have thought and we just need to track down some other, unrelated error.
In any case, I likely won't have a chance to look into this myself for a while since I'm trying hard to get Statiq Docs out the door. I'll certainly keep the issue open and revisit when I next have a chance to go through the backlog here.
Excuse my extreme fashion, I'm quite late.
I've found that this exception occurs when NavigationManager.Initialize
is invoked by the StaticComponentRenderer
, due to the ViewContext.HttpContext.Request
not containing the url data needed to construct the NavigationManager.BaseUri
and NavigationManager.Uri
.
My workaround of choice was to set the url properties on the HttpContext.Request
prior to the ComponentTagHelper
's usage (e.g. within _ViewStart.cshtml
):
@using Microsoft.AspNetCore.Http
@{
var url = new Uri( Document.GetLink( true ) );
HttpContext.Request.Host = new HostString( url.Host );
HttpContext.Request.Path = url.AbsolutePath;
HttpContext.Request.Scheme = url.Scheme;
}
NOTE: The
Host
setting must be set on theBootstrapper
to create an absolute uri (see Linking to Documents).
I believe, ideally, RazorCompiler.GetViewContext
could set these properties by default, or, the method be pulled out to an IViewContextFactory
service that could be overridden via Bootstrapper.ConfigureServices
.
Finally, I've published a Proof of Concept for reference. The PoC also includes a CopyStaticWebAssets
module, which reads the underlying manifest file used by the runtime, to copy the Blazor _framework
files (as well as all other RCL content) to the output
folder.