Razor + HtmlRenderer でブログをまた新しくした(今年2回目)

またブログを新しくしました。中身だけ。

これまではBlazor WebAssemblyで作ってました。C#で書きたいしBlazorでも触ってみようかという軽い気持ちで。ただ、Blazor WASMはやっぱり重たいですね。BlazorWasmPreRendering.Buildを使ったプリレンダリングなどの工夫はしたりしてたんですが、それでも全然コンテンツのないこのサイトにアクセスしただけで、ランタイム全部ダウンロードしてもらうのもなあ~と思い、やっぱりやめました。

でいわゆるSSG(Static Site Generation)を使ってhtmlを生成する構成にする、ただしC#で書きたい、ということでいろいろ探したんですが、.NET 8からRazorを直接htmlにレンダリングできるHtmlRendererというのがあるんですね。

ASP.NET Core の外部で Razor コンポーネントをレンダリングする | Microsoft Learn

全然知らなかった…

これは、HTML フラグメントを生成したいシナリオに便利です。たとえば、メール コンテンツの生成、静的サイト コンテンツの生成、コンテンツのテンプレート エンジンの構築などです。

って書いてあります。これでいいじゃない。

使い方も簡単でレンダリングしたいRazorコンポーネント(ここではPage)を用意して、あとは以下のように書くだけです。

await using var renderer = new HtmlRenderer(serviceProvider, serviceProvider.GetRequiredService<ILoggerFactory>());
var html = await renderer.Dispatcher.InvokeAsync(async () =>
{
    var parameters = new Dictionary<string, object?>
    {
        ["Title"] = "Hello, world!"
    };
    var document = await renderer.RenderComponentAsync<Page>(ParameterView.FromDictionary(parameters));
    return document.ToHtmlString();
});

簡単!

当然ですが単にhtmlを生成するだけなのでインタラクティブなことはできません。また、OnAfterRenderなんかも呼ばれません。なので使いどころは選びそうですが、ブログのような静的なコンテンツを生成するだけであれば十分ですね。