😸

.NET 6 の Blazor で追加された <head> タグの中を変更する機能の紹介

2021/09/27に公開

今日も .NET 6 の ASP.NET Core Blazor WebAssembly の機能紹介をしたいと思います。

昨日はクエリパラメーターとコンポーネントのプロパティを簡単に紐づける機能の紹介でした。

https://zenn.dev/okazuki/articles/blazor-wasm-rc1-queryparam

こういう細かいところの使い勝手向上系は割と好きです。今日紹介するのもそういう系になります。

<head> タグの中をページごとに変える

タイトル通りのことが出来るようになりました。Blazor では JavaScript との相互運用機能とかもあるので、それらを駆使すれば今までもやろうと思えばやれた(はず)なのですが標準機能の範囲で Blazor が準備してくれている箱庭の中の世界だけで簡単にできるようになった点が個人的にはポイントかなと思います

HeadOutlet コンポーネント

この機能を実現してくれているのが HeadOutlet コンポーネントです。.NET 6 RC 1 時点のプロジェクトテンプレートの Program.cs を見ると head::after (head タグの最後のコンテンツ) に HeadOutlet コンポーネントを追加するコードが追加されています。

Program.cs
using BlazorApp5;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after"); // 追加されてる!

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();

このコンポーネントが追加されている状態だと各ページで PageTitle コンポーネントや HeadContent コンポーネントを利用して <title> タグや <head> タグのコンテンツをページから設定できます。例えば以下のようなページを作るとします。

Index.razor
@page "/"

@* title タグの中身を設定できる *@
<PageTitle>
    いんでっくす
</PageTitle>

@* head タグに追加する内容を設定できる *@
<HeadContent>
    <meta name="description" content="@_myDescription" />
</HeadContent>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

@code {
    private string _myDescription = "hogehoge fugafuga";
}

このページに遷移すると以下のようにページタイトルが「いんでっくす」になっていることが確認できます。さらにブラウザーの開発者ツールで確認すると meta タグが追加されていることも確認できます。

因みに、このように別のコンポーネントにあるコンテンツをとってきてレンダリングするコンポーネントを作るための共通的な仕組みが出来たのかと思ってソースも見てみたのですが internal なクラスやインターフェースが登場してきたのでそこでソースを追いかけるのを辞めました…。先日の ErrorBoundary でも internal なインターフェースを実装していたりして結構一般人では手が出せないような仕組みで実装されているものに最近良く当たります。

因みに、この方法ですが Index.razor (デフォルトのプロジェクトテンプレートで初期表示されるページ) が最初に表示されたタイミングでは PageTitle コンポーネントで指定した内容が title タグに設定されません。詳細は追ってないのですが、デフォルトの title タグの中身を取得するようなコードがあったような気がしたので、試しに index.html から <title>BlazorApp5</title> のような title タグ自体を無くすか <title></title> のように中身を空にすると初回表示時にも PageTitle コンポーネントで指定した内容が表示されていました。

多分、本当に初回はサイトのタイトルとして指定されている index.html の内容を尊重してるのかな…?と思います。個人的な想像ですけど。
正式なドキュメントが整備されたタイミングあたりで、ここら辺の挙動とかはきっと書かれると信じています。

まとめ

ということで、今回も細かい機能の紹介でした。

でも、こういう細かいところの改善が全体としての使い勝手の向上につながっていくと思うので個人的には好きです。

では、良い Blazor ライフを!

Microsoft (有志)

Discussion