如何在Blazor中设置页面标题?

30
作为一个 SPA 框架,Blazor 是否可以为每个页面设置页面标题?
我目前正在开发使用 Blazor WebAssembly 的项目,并且无法确定如何添加页面标题,因为 SPA 中只有一个 index.html 文件。但是,如果能为每个“页面”设置标题,将会非常有用。
12个回答

27
ASP.NET CORE 6.0 开始,官方文档 表示我们可以使用 PageTitle 组件轻松地影响 HTML <title> 标签元素。 在 Program.cs 中添加 HeadOutlet 组件。
builder.RootComponents.Add<HeadOutlet>("head::after");

然后使用 PageTitle 组件

<PageTitle>@title</PageTitle>

更新1:

看起来这个API已经被搁置以进一步改进。官方文档链接已经删除了。这是跟踪同样问题的github问题。一旦API最终在文档中可用,我会更新答案。

更新2:

上述问题已经得到解决,ASP.NET Core团队添加了<PageTitle>组件到ASP.NET Core 6.0。我也相应地更新了答案。


标题在这里不起作用,但标题是可以的。 - Thiago Loureiro
目前在 Blazor 中尚未实现此功能。如答案中所述,请跟踪 Github 问题以获取 <Title> 组件的官方发布。 - fingers10
2
program.cs 文件中,不再需要使用 builder.RootComponents.Add<HeadOutlet>("head::after");。现在可以直接使用 <PageTitle> 元素。 - Tyson Gibby
@TysonGibby 尽管我也做了同样的事情,但直到我添加了 Program.cs 部分才起作用。 - Ziad Akiki
2
@ZiadAkiki,文档已更新,显示您现在需要在_Layout.cshtml文件中添加出口组件用于预渲染项目。这意味着(模糊)您仍然需要将其添加到其他wasm项目的program.cs中。 - Sinaesthetic
@TysonGibby 在 program.cs 中添加 HeadOutlet 对于 net-7.0 Blazor WebAssembly 仍然是必需的。 - James McCormack

23

注意:从 .Net 6.0 开始,官方提供了更改标题的支持,因此下面的解决方案不再需要。

  1. 在您的 index.html(或包含的 .js 文件)中提供以下脚本:

<script>
     setTitle = (title) => { document.title = title; };
</script>
  1. 在每个页面中注入jsinterop:

@inject IJSRuntime JSRuntime;
  • 每次渲染后,将文档标题设置为您选择的值:

  • @code
    {
       protected override async Task OnAfterRenderAsync(bool firstRender)
       {
          await JSRuntime.InvokeVoidAsync("setTitle", "this is the new title"); ;        
       }    
    }
    

    InvokeVoidAsync 应该只在 firstRender 的值为 true 时调用一次。上面的代码会在每次 OnAfterRenderAsync 发生时执行。 - enet
    1
    @enet:没错,但上面的代码是针对我的页面主体由不同组件交替出现的用例,我希望页面标题能够反映当前显示的组件。通过在每个“OnAfterRenderAsync”上执行此代码,我可以确保每当主组件更改时更新标题。 - Johan Donne
    @CBBSpike:这个示例是针对 Blazor(服务器端)的预览版本编写的。您可以将脚本添加到 _Host.cshtml 中(例如,在 blazor.js 脚本之后)。 - Johan Donne
    这是基于我的经验最好的方法。https://dev59.com/bFMH5IYBdhLWcg3wpgpd#68271272 - Ives.me
    1
    .NET 6为服务器端和客户端Blazor都提供了官方支持。我建议使用官方API进行开发,这些API在一些最近/更新的答案中有所描述。 - Swimburger
    显示剩余3条评论

    18
    在ASP.NET CORE 5.0中,添加了一个新的标题组件。
     <Title value="Page title" /> 
    

    MSDN参考:https://learn.microsoft.com/zh-cn/dotnet/aspnet/core/blazor/fundamentals/additional-scenarios?view=aspnetcore-5.0#influence-html-head-tag-elements

    首先在组件中添加using语句

    @using Microsoft.AspNetCore.Components.Web.Extensions.Head
    
    你可以使用该命令安装(如果未安装)。
    dotnet add package Microsoft.AspNetCore.Components.Web.Extensions --version 5.0.0-preview9.20467.1
    

    我写这篇文章时,版本号是5.0.0-preview9.20467.1。请查看Nuget网址以获取最新版本。

    Nuget网址:https://www.nuget.org/packages/Microsoft.AspNetCore.Components.Web.Extensions/

    接着添加Title标签即可。

    <Title Value="My page title" />
    

    请参见下图示例输出

    enter image description here


    3
    你难道不喜欢微软的文档吗? 每次我在网上跟随微软文档的链接时,内容似乎都与创建链接时不同。 - JonathanPeel
    1
    我还需要将以下脚本添加到我的index.html中才能使其正常工作:<script src="_content/Microsoft.AspNetCore.Components.Web.Extensions/headManager.js"></script> - Jason D

    8

    .NET 6 RC1引入了PageTitle组件来处理此场景。 PageTitle组件位于Microsoft.AspNetCore.Components.Web命名空间内。

    您可以将组件放置在Blazor应用程序中的任何位置,PageTitle的内容将反映为您页面的标题。如果您有多个PageTitle组件,则最后呈现的一个将成为您页面的标题。

    在这种情况下,标题将是“Page Title 2”:

    @page "/counter"
    
    <PageTitle>Page Title 1</PageTitle>
    <PageTitle>Page Title 2</PageTitle>
    

    要让 PageTitleHeadContent 生效,您需要将 HeadOutlet 添加为根组件。 如果您完全在客户端使用 Blazor WASM(没有预渲染),则需要在将 App 添加为根组件后,在 Startup.cs 文件中添加以下行:
    builder.RootComponents.Add<HeadOutlet>("head::after");
    

    head::after CSS选择器指示在何处呈现HeadOutlet的输出,这将被用于HeadContent,但如果已经存在标题标签,则现有的标题标签将被更新。

    如果您正在使用具有预渲染功能的Blazor WASM,则应将以下行放置在_Layout.cshtml文件的头部:

    <component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />
    

    假设您已经按照Microsoft的文档设置Blazor WASM预渲染的步骤拥有_Layout.cshtml文件。
    如果您想了解更多细节,请参阅我在Telerik博客上写的关于PageTitle、HeadContent和HeadOutlet的博客文章
    我还发现了一些非常新的Microsoft文档,涉及到PageTitle、HeadContent等内容

    6

    针对 .NET Core 3.1 的开发者

    感谢这篇文章,你可以创建一个可重用的组件。

    将下面的脚本添加到js文件中,或添加到index.html文件中。

    在此输入图片描述

    <!DOCTYPE html>
    <html>
    
    <head>
    ...
    </head>
    
    <body>
    ...
        <script>
            window.setTitle = (title) => {
                document.title = title;
            }
        </script>
    </body>
    
    </html>
    

    在共享文件夹中创建一个名为PageTitle.razor的新组件。

    folder layout

    @inject IJSRuntime JsRuntime;
    
    @code {
        [Parameter]
        public string Title { get; set; }
    
        protected override async Task OnInitializedAsync()
        {
            await SetTitle();
        }
    
        private async Task SetTitle()
        {
            await JsRuntime.InvokeVoidAsync("setTitle", Title);
        }
    }
    

    将以下代码添加到您要更改名称的 Razor 页面中:

    <PageTitle Title="Home sweet home" />
    

    Index.razor

    Final result


    1
    对于“InvalidOperationException: JavaScript互操作调用不能在此时发出。这是因为组件正在静态呈现。启用预呈现时,JavaScript互操作调用只能在OnAfterRenderAsync生命周期方法期间执行。”,请在“protected override Task OnAfterRenderAsync(bool firstRender)”中进行处理。 - Tom Charles Zhang

    2

    对于在.net6.0中使用的Blazor Server

    请在_Host.cshtml文件中的<head>标签内添加以下代码片段:

    @using Microsoft.AspNetCore.Components.Web
    <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
    

    例子

    @page "/"
    @using Microsoft.AspNetCore.Components.Web
    <head>   
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Title Placeholder</title>
     <base href="~/" />
     <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
     <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
     <link href="css/site.css" rel="stylesheet" />        
    </head>
    

    然后在您的各种 Razor 组件中,您可以使用 <PageTitle> 标签。

    ExampleComponent.razor

    @page "/ExampleComponent"
    <PageTitle>Supplier Documents</PageTitle>
    

    微软文档


    谢谢!在Blazor Server中,添加<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />是我缺失的部分。 - creanium

    2

    自 .NET 6 开始,您只需使用以下代码:

    <PageTitle>@YourTitle</PageTitle>
    

    1
    你可以使用这个 Nuget 包。它可以更改你的 Blazor 页面标题,甚至可以更改图标,以显示通知。请查看文档获取更多详细信息。

    enter image description here

    演示应用程序中尝试一下。

    1

    助手jsakamoto Toolbelt.Blazor.HeadElement是唯一能够正确解决页面标题更改的工具。归根结底,更改标题的主要原因是为了帮助SEO,因此必须进行服务器端预渲染。

    Blazor Head Element Helper

    enter image description here

    要使用这个帮助程序,请访问作者在https://dev.to/j_sakamoto/yet-another-way-to-changing-the-page-title-in-blazor-and-more-43k上的说明。

    更多信息请参见https://github.com/jsakamoto/Toolbelt.Blazor.HeadElement/#blazor-head-element-helper-

    我想请求这个stackoverflow问题的作者,将这个答案选为最佳答案。


    当你使用Blazor时,是因为你想用C#编程,而不是JS,所以我认为这是正确的答案,因为你可以完全不用JS就完成所需的工作,因为所有的JS都嵌入在Toolbelt.Blazor.HeadElement组件中。太棒了! - Lucky Brain

    0

    我需要一个友好的SEO解决方案,我已经找到了自己的解决方案。也许你可以使用它,这个解决方案是多语言的。

    我们需要一个辅助静态类:

    public static class MetaHelper
    {
        public class MetaModel
        {
            public MetaModel(string title, string description)
            {
                Title = title;
                Description = description;
            }
            public string Title { get; set; }
            public string Description { get; set; }
        }
    
        public static MetaModel GetMeta(string path)
        {
            var culture = CultureHelper.GetCultureSlug();
            // culture is ".com/en/faqs" or ".com/de/faqs" etc
            path = path.Replace($"{culture }/", "");
    
            if (path == "faqs")
            {
                return new MetaModel("Faq - website", "Frequently Asked Questions about ....");
            }
            else if (path == "page2")
            {}......
    
    
            return new MetaModel("Web site - Default Name", "Default description");
        }
    }
    

    我们可以在 _host.cshtml 页面中使用这个辅助函数

    @{
    Layout = null;
    
    var meta = MetaHelper.GetMeta(Request.Path);
    }
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>@meta.Title</title>
        <meta name="description" content="@meta.Description">
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接