Blazor NavMenuにページが表示されない原因と解決策|MyButton.razor(MyPage)をメニューに追加する方法

Blazor の学習中に Pages フォルダへ MyButton.razor(@page "/MyPage")を追加したのに、左側メニュー(NavMenu)にリンクが増えない…。これは不具合ではなくテンプレートの仕様です。この記事では、メニューに表示する最短手順と、つまずきやすい確認ポイントをまとめます。

目次

症状:新しく追加した Razor コンポーネントがメニューに出てこない

Blazor のテンプレートを触り始めた直後に、次のような状態になることがあります。

  • Pages フォルダに MyButton.razor を追加し、先頭に @page "/MyPage" を書いた
  • ビルドは通る(ページ自体は存在している)
  • しかし、画面左側のナビゲーションメニュー(NavMenu)には新しいリンクが表示されない
  • 最初からある「Home」「Counter」「Fetch data(または Weather)」などの 3 つだけが表示され続ける

結論から言うと、ページの追加=メニューの自動追加 ではありません。ルーティングは増えても、メニューは増えないため、手動で NavMenu に項目を足す必要があります。

まず押さえるポイント:原因と対処はシンプル

迷ったときは、いったん次の対応表に戻ると切り分けが早いです。

起きていること原因対処確認方法
メニューに MyPage が出ないNavMenu は自動生成されないNavMenu.razor に <NavLink> を追記左メニューにリンクが増えたか
メニューは出たがクリックしても遷移しないhref と @page が不一致 / ベースパス不一致href をルートに合わせる(必要なら相対パスに)アドレスバーに URL を直接入力して表示できるか
直接入力でも表示できない@page がない / ビルドエラー@page を確認、ビルドログ確認dotnet build とブラウザ Console

結論:NavMenu は自動生成されないので、NavMenu.razor にリンクを追記する

Blazor では、@page ディレクティブ(または [Route] 属性)が付いたコンポーネントは URL ルートとして認識されます。一方で、左メニューの NavMenu は「ただの部品」です。テンプレートは NavMenu の中にあらかじめ数個の <NavLink> を固定で書いているだけなので、新規ページを作っても自動で増えません。

要素役割自動で増える?代表ファイル
ルーティング@page の情報を見て URL とコンポーネントを結び付ける増える(@page を追加すればルートは増える)App.razor / Routes.razor など
NavMenu画面に表示する「メニュー項目」を並べるだけ増えない(自分でリンクを書き足す)NavMenu.razor

対応手順:MyButton(/MyPage)をメニューに表示する

NavMenu.razor を開く

プロジェクトのテンプレートや .NET の世代によって配置が少し違います。まずは「NavMenu.razor」を検索して開くのが確実です。よくあるパスは次のとおりです。

テンプレート例NavMenu の場所(例)補足
Blazor WebAssembly / Server(従来テンプレート)Shared/NavMenu.razor学習教材や旧テンプレートでよく見かける構成
.NET 8 以降の新しめの構成Components/Layout/NavMenu.razorComponents 配下にレイアウト関連がまとまっていることが多い
独自にフォルダを整理している場合プロジェクト内検索で NavMenu を探すレイアウトを自作していると複数存在することも

既存のメニュー項目を参考に、MyPage 用の NavLink を追加する

NavMenu.razor を開くと、テンプレートの既存リンク(Home/Counter/Fetch data)が並んでいるはずです。その近くに、同じ構造で MyPage 用のリンクを 1 つ追加します。

&lt;div class="nav-item px-3"&gt;
    &lt;NavLink class="nav-link" href="/MyPage"&gt;
        &lt;span class="bi bi-list-nested-nav-menu" aria-hidden="true"&gt;&lt;/span&gt;
        MyPage
    &lt;/NavLink&gt;
&lt;/div&gt;

このコードのポイントは次のとおりです。

  • href はルートと一致:ページ側が @page "/MyPage" なら、href="/MyPage" にします。
  • 表示名は自由:メニューに表示する文字は「MyPage」でも「現在時刻ボタン」でも分かりやすければ OK です。
  • アイコンはテンプレートに合わせる:最近のテンプレートは Bootstrap Icons(bi ...)を使うことが多い一方、古いテンプレートは Open Iconic(oi ...)の場合があります。見た目だけの差なので、最初はアイコン部分を消しても動作確認はできます。

サブディレクトリ公開の可能性があるなら、相対 href も検討する

開発環境(https://localhost:xxxx/)では href="/MyPage" で問題が出にくい一方、アプリをサブディレクトリ配下(例:https://example.com/app/)で公開する予定があるなら、次のように 先頭スラッシュなしの相対指定が安全なことがあります。

&lt;NavLink class="nav-link" href="MyPage"&gt;MyPage&lt;/NavLink&gt;

/MyPage は「ドメイン直下」を指すため、ベースパス運用と相性が悪いケースがある、という点だけ覚えておけば十分です。学習モジュールの範囲では、まずは質問文どおり /MyPage で理解してから、公開形態に応じて調整すると迷いません。

ページ側の @page と一致しているかを確認する

「メニューに出ない」原因の大半は、NavMenu の href と、ページの @page が一致していないことです。特に学習中は、ファイル名(MyButton)とルート名(MyPage)がズレていると混乱しやすいので、いったん表で確認しておくと安全です。

MyButton.razor の先頭NavMenu の href結果コメント
@page "/MyPage"href="MyPage"OKベースパスに追従しやすい
@page "/MyPage"href="/MyPage"OKドメイン直下で運用するなら分かりやすい
@page "/MyPage"href="/MyButton"NGファイル名とルートを混同している典型例
@page "/mypage"href="/MyPage"ほぼOKルーティングは大抵大文字小文字を吸収しますが、表記ゆれは避けるのがおすすめ

再ビルドしてブラウザを更新する

NavMenu.razor を保存したら、次を順に実行します。

  1. プロジェクトを再ビルド(または再実行)
  2. ブラウザをリロード(開発中に反映されない場合は強制更新)
  3. 左メニューに「MyPage」の項目が増えていることを確認

Hot Reload が効いている環境でも、レイアウト周りの差分が UI に反映されないことがあります。その場合は「いったん停止→再起動」「ブラウザの強制再読み込み(Ctrl+F5 / Shift+Reload)」までやると切り分けが早いです。

補足:メニューに追加しなくてもページにアクセスできる理由

NavMenu にリンクがなくても、ページが「存在しない」わけではありません。@page を書いた時点でルーティングは有効になっているため、アドレスバーに https://(あなたのURL)/MyPage と直接入力すれば表示できます。

つまり、今回の問題は「ルートが登録されていない」ではなく、NavMenu が新しいルートを自動的に列挙する仕組みではない、という点に集約されます。

MyButton.razor は「ページ」にも「部品」にもなれる

Blazor の Razor ファイルは、書き方しだいで次の 2 通りの役割を持ちます。

  • ページ(ルーティング対象):@page を書く。URL で直接開ける。
  • 再利用する部品(コンポーネント):@page を書かない。他のページから <MyButton /> のように呼び出して使う。

「ボタン部品を作っただけなのにメニューに出したい」というケースでは、実は “ページにする必要があるのか” を見直すのも手です。学習目的で動作確認するならページ化(@page あり)で OK、アプリの部品として使いたいならページ化しない(@page なし)方が設計がシンプルになります。

それでも表示されないときのチェックリスト

NavMenu を編集したのに反映されない場合、原因はメニュー追記以外にあることもあります。ここからは、実務でも遭遇しやすい確認ポイントを「短時間で潰せる順」に並べます。

NavMenu を編集しているファイルが「本当に表示されている NavMenu」か

プロジェクトによっては NavMenu.razor が複数あることがあります。例えば、テンプレートをカスタマイズして新しいレイアウトを追加した場合、古い NavMenu を編集しても画面に反映されません。

確認方法の一例として、表示中のレイアウト(多くは MainLayout.razor)を開き、メニュー部分で読み込んでいるコンポーネントを見ます。

&lt;!-- MainLayout.razor の例 --&gt;
&lt;div class="sidebar"&gt;
    &lt;NavMenu /&gt;
&lt;/div&gt;

<NavMenu /> が別名(例:<MyNavMenu />)になっていたり、レイアウト自体が切り替わっていたりする場合は、編集対象を見直してください。手早く見分けるなら、NavMenu に一時的に TEST の文字を入れて画面に出るか確認する方法が確実です。

MyButton.razor の先頭に @page があるか

質問文では「@page "/MyPage" を付けた」となっていますが、実際には @page がコメントの下に埋もれていたり、条件付きで無効になっていたりするケースがあります。最小構成の例は次のとおりです。

@page "/MyPage"

&lt;h1&gt;MyPage&lt;/h1&gt;

&lt;p&gt;ここにボタンなどを置く&lt;/p&gt;

目安として「@page が 1 行目付近にある」状態にしておくと、見落としが減ります。

ビルドエラーが隠れていないか

「画面は開けるがメニューだけ更新されない」ケースでも、実はコンソールに警告やエラーが出ていることがあります。特に、追加した NavLink の中で CSS クラス名を間違えたり、コンポーネント名のタイポがあると、ビルドに失敗して古い状態が表示され続けます。

  • IDE のエラー一覧を確認
  • ターミナルで dotnet build を実行してエラーがないか確認
  • ブラウザの開発者ツール(Console)を確認

href の書き方が公開環境のベースパスと合っているか

開発環境では問題なくても、公開形態(IIS/Reverse Proxy/GitHub Pages など)によっては href="/..." が原因で意図しない場所に飛ぶことがあります。心当たりがある場合は、リンク指定を相対に寄せるか、<base href="..."> の設定(テンプレート側)を含めて見直すと改善しやすいです。

NavLink の Match を理解しておく

「リンクは出たが、選択中のハイライトが期待通りにならない」という副作用が出ることもあります。Blazor の <NavLink> は、現在の URL と href の一致度でアクティブ判定をします。

  • トップページ(Home)は部分一致だと常にアクティブになりがちなので、Match="NavLinkMatch.All" を付けるのが定番です。
  • それ以外はデフォルト(部分一致)でも問題ないことが多いです。
&lt;NavLink class="nav-link" href="" Match="NavLinkMatch.All"&gt;
    Home
&lt;/NavLink&gt;

MyPage 側は通常デフォルトのままでよいですが、「/MyPage」と「/MyPage/Detail」のように子階層を持つ設計にしたい場合は、意図したアクティブ表示になるよう Match の方針を決めておくと UX が整います。

実務で役立つ:NavMenu の追加をミスりにくくする書き方

学習段階では 1 行追加で十分ですが、ページ数が増えると「コピペのズレ」「リンクだけ更新し忘れ」といった事故が起きやすくなります。ここでは、NavMenu を少しだけ整理して、運用しやすくする方法を紹介します。

メニュー項目をリスト化して foreach で描画する

NavMenu にリンクを直書きするのではなく、メニュー定義をリストにしておくと、表記揺れや重複を減らせます。例えば次のように「タイトル」と「URL」を 1 箇所に集めます。

@code {
    private readonly (string Title, string Href, string IconClass)[] Items =
    [
        ("Home", "", "bi bi-house-door-fill"),
        ("Counter", "counter", "bi bi-plus-square-fill"),
        ("Fetch data", "fetchdata", "bi bi-list-nested"),
        ("MyPage", "MyPage", "bi bi-list-nested-nav-menu")
    ];
}

そして描画側は繰り返しにします。

@foreach (var item in Items)
{
    &lt;div class="nav-item px-3"&gt;
        &lt;NavLink class="nav-link" href="@item.Href"&gt;
            &lt;span class="@item.IconClass" aria-hidden="true"&gt;&lt;/span&gt;
            @item.Title
        &lt;/NavLink&gt;
    &lt;/div&gt;
}

この形にすると、次のメリットがあります。

  • 追加・削除が「配列に 1 行足す/消す」で済み、編集箇所が減る
  • メニュー表示名を変えるときに、誤って href を壊しにくい
  • チーム開発で差分が読みやすい(レビューしやすい)

一方で、テンプレートの CSS 構造を大きく変えるとレイアウトが崩れることがあるので、まずは「既存の HTML 構造を維持したまま foreach に置き換える」方針が安全です。

メニューに出すページと、出さないページを分ける

実務では、URL は存在するがメニューに出さないページ(例:ログイン後だけ見せる管理画面、詳細画面、ウィザードの中間ページ)も増えます。そうした場合は、NavMenu を「表示したいページだけを書く場所」と割り切るのが分かりやすいです。

  • ナビゲーション=ユーザーが迷わないための導線
  • ルーティング=アプリ内部の画面遷移の入口

この 2 つを同一視しないことが、Blazor アプリを設計しやすくするコツです。

よくある Q&A

ファイル名が MyButton.razor でも href は MyButton になりますか?

なりません。URL はファイル名ではなく、@page に書いたルートで決まります。ファイル名は「開発者が管理しやすいように付ける名前」で、URL とは独立です。今回の例なら、ファイル名が MyButton でも URL は /MyPage です。

自動でルート一覧を拾ってメニューを生成できませんか?

技術的には可能です(アセンブリから [Route] 属性を持つコンポーネントを反射で列挙する、独自属性でメニュー名を付ける等)。ただし、実務では「並び順」「表示名」「権限による表示/非表示」「アイコン」「グルーピング」などの要件がすぐ増えるため、結局は手動管理に戻るケースが多いです。まずは NavMenu に明示的に書く方法を理解しておくのが近道です。

メニューに追加したのにクリックしても画面が切り替わりません

次の順で確認してください。

  • リンク先の URL が正しいか(href と @page が一致しているか)
  • ページ側にビルドエラーがないか
  • ブラウザの Console に例外が出ていないか
  • サブディレクトリ公開の場合、href="/..." が原因で別の場所へ飛んでいないか

まとめ:Blazor で「ページは増えたのにメニューが増えない」は正常

Blazor では、新しく Razor コンポーネント(ページ)を作って @page を追加するとルーティングは有効になります。しかし、NavMenu はルート一覧を自動で取り込む仕組みではないため、メニューに表示したい場合は NavMenu.razor に <NavLink> を追記する必要があります。

まずは「NavMenu を開いて 1 項目追加」という基本を押さえ、次に「ベースパス運用」「Match」「メニュー管理の整理」に進むと、学習と実務の両方でつまずきにくくなります。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次