使用 Blazor 设置 html 元标记

Adr*_*ink 6 meta-tags blazor blazor-server-side

这是参考#10450。

目标:使用来自页面本身的数据设置元标签(标题、描述等)以用于 SEO 和开放图谱目的。使用 Javascript 互操作不会有帮助,因为页面将无法被抓取。

我使用了@honkmother 的建议,并将基本组件进一步移到树上以封装标签<html>,但由于某种原因,这影响了路由。所有链接都带有前缀~/,我似乎无法理解为什么。

如果有人有兴趣看一下,我在这里创建了一个示例存储库。

_Hosts.cshtml

@page "/"
@namespace BlazorMetaTags.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = null;
}

<!DOCTYPE html>
<component type="typeof(AppBase)" render-mode="ServerPrerendered" />
Run Code Online (Sandbox Code Playgroud)

应用程序库.cs

using BlazorMetaTags.Shared;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;

namespace BlazorMetaTags
{
    public class AppBase : ComponentBase
    {
        protected override void BuildRenderTree(RenderTreeBuilder builder)
        {
            builder.OpenElement(0, "html");
            builder.AddAttribute(1, "lang", "en");

            builder.OpenElement(2, "head");
            builder.OpenComponent<Head>(3);
            builder.CloseComponent();
            builder.CloseElement();

            builder.OpenElement(3, "body");

            builder.OpenElement(4, "app");
            builder.OpenComponent<App>(5);
            builder.CloseComponent();
            builder.CloseElement();

            builder.OpenComponent<Body>(6);
            builder.CloseComponent();

            builder.AddMarkupContent(7, " <script src='_framework/blazor.server.js'></script>");
            builder.CloseElement();
            builder.CloseElement();

        }

    }

    public class MetaTags
    {
        public string Title { get; set; } = "";

        public string Description { get; set; } = "";
    }
}
Run Code Online (Sandbox Code Playgroud)

Head.razor 组件用于设置元标记

@inject AppState _appState

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title>@_appState.MetaTags.Title</title>
    <meta name="description" content="@_appState.MetaTags.Description">

    <base href="~/" />
    <link rel="stylesheet" href="/css/bootstrap/bootstrap.min.css" />
    <link href="/css/site.css" rel="stylesheet" />
</head>

@code {

    protected override async Task OnInitializedAsync()
    {
        _appState.OnChange += StateHasChanged;
    }

}
Run Code Online (Sandbox Code Playgroud)

身体剃须刀

<div id="blazor-error-ui">
    <environment include="Staging,Production">
        An error has occurred. This application may no longer respond until reloaded.
    </environment>
    <environment include="Development">
        An unhandled exception has occurred. See browser dev tools for details.
    </environment>
    <a href="" class="reload">Reload</a>
    <a class="dismiss"></a>
</div>
Run Code Online (Sandbox Code Playgroud)

应用程序状态.cs

using System;

namespace BlazorMetaTags
{
    public class AppState
    {
        public MetaTags MetaTags { get; private set; } = new MetaTags();

        public event Action OnChange;

        public void SetMetaTags(MetaTags metatags)
        {
            MetaTags = metatags;
            NotifyStateChanged();
        }

        private void NotifyStateChanged() => OnChange?.Invoke();
    }
}
Run Code Online (Sandbox Code Playgroud)

启动.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddScoped<AppState>();
    services.AddSingleton<WeatherForecastService>();
}
Run Code Online (Sandbox Code Playgroud)

Adr*_*ink 0

正如Meisam Dehghan 在评论中所建议的,正确的解决方案是改变

<base href="~/" />
Run Code Online (Sandbox Code Playgroud)

到

<base href="/" />
Run Code Online (Sandbox Code Playgroud)

这对我有用!