Skip to content

Blazor html meta tags #18050

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
thewebchameleon opened this issue Dec 28, 2019 · 1 comment
Closed

Blazor html meta tags #18050

thewebchameleon opened this issue Dec 28, 2019 · 1 comment
Labels
area-blazor Includes: Blazor, Razor Components

Comments

@thewebchameleon
Copy link

thewebchameleon commented Dec 28, 2019

This is in reference to #10450.

Goal: Set meta tags (title, description etc) for SEO and Open Graph purposes with data coming from the page itself. Using the Javascript interop won't help as pages won't be able to be crawled.

I have used a suggestion by @Honkmother and moved the base component further up the tree to encapsulate the <html> tag but for some reason this has affected routing. All links are prepended with ~/ and I can't seem to understand why.

I have created an example repo here if anyone is intersted in taking a look.

_Hosts.cshtml

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

<!DOCTYPE html>
<component type="typeof(AppBase)" render-mode="ServerPrerendered" />

AppBase.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; } = "";
    }
}

Head.razor component to set the meta tags

@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;
    }

}

Body.razor

<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>

AppState.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();
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddScoped<AppState>();
    services.AddSingleton<WeatherForecastService>();
}
@pranavkm
Copy link
Contributor

@thewebchameleon I'm not sure rendering the script tag from a component is going to work. It's required to bootstrap Blazor Server. That said, as you pointed out, the linked issue - #10450 - already tracks the work to be done here. If you need specific help using using Blazor, please use StackOverflow with the asp.net-core-blazor tag.

@pranavkm pranavkm added the area-blazor Includes: Blazor, Razor Components label Dec 30, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Jan 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

2 participants