Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

Add simpler API for invoking prerendering without using tag helper #607

Closed
@SteveSandersonMS

Description

@SteveSandersonMS

Although the asp-prerender-module tag helper is usually the most convenient and natural way to invoke prerendering, there are some cases where you'd want to do it from controller code, or from a code block in your Razor page. For example, you might want to receive back additional custom data values from prerendering, and then maybe use them to set the page title or similar. Or you might want to change how the globals values are serialized and delivered to the client.

Currently it is possible to do this by invoking Prerenderer.RenderToString directly. However it's inconvenient, because you have to duplicate some non-obvious logic from the tag helper. For example, to run prerendering from controller code, currently you need something like this:

var requestFeature = Request.HttpContext.Features.Get<IHttpRequestFeature>();
var unencodedPathAndQuery = requestFeature.RawTarget;
var unencodedAbsoluteUrl = $"{Request.Scheme}://{Request.Host}{unencodedPathAndQuery}";
var prerenderResult = await Prerenderer.RenderToString(
    hostEnv.ContentRootPath,
    nodeServices,
    new JavaScriptModuleExport("ClientApp/dist/main-server"),
    unencodedAbsoluteUrl,
    unencodedPathAndQuery,
    /* custom data parameter */ null,
    /* timeout milliseconds */ 15*1000,
    Request.PathBase.ToString()
);

ViewData["SpaHtml"] = prerenderResult.Html;
ViewData["Title"] = prerenderResult.Globals["pageTitle"];

We should consider migrating this logic out of PrerenderTagHelper and into some new DI service class that PrerenderTagHelper starts using. Then developers will be able to grab instances of that new service class and do custom prerendering much more easily. Ideally, you'd be able to do something like this directly in a Razor view:

@inject Microsoft.AspNetCore.SpaServices.Prerendering.IPrerenderer prerenderer
@{
    var prerenderResult = await prerenderer.RenderToString("ClientApp/dist/main-server");
}
...
<title>@prerenderResult.Globals["pageTitle"]</title>
<app>@Html.Raw(prerenderResult.Html)</app>

There could be an options param for overriding things like the request URL, timeout, etc., but by default it would use values from the context automatically like asp-prerender-module already does.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions