Why is blazor HeadOutlet rendering after the App
Asked Answered
B

2

9

I'm using a HeadOutlet on a server side pre-rendered net6.0 app to set some header tags such as meta description but the server renders the app first and then the headers which makes search engines ignore it.

@page "/"
@namespace Example.Pages
@using Microsoft.AspNetCore.Components.Web
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

@{
    Layout = null;
}

<!DOCTYPE html>
<html lang="en">
<head>
    <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
    <base href="~/" />

    <link href="css/site.css" rel="stylesheet" />
    <link rel="preconnect" href="https://fonts.gstatic.com">
</head>
<body>
    <component type="typeof(App)" render-mode="ServerPrerendered" />

    <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 href="#" class="dismiss">🗙</a>
    </div>

    <script src="_framework/blazor.server.js"></script>
    <script src="~/outsideHandleContainerJsInterop.js"></script>
</body>
</html>
@page "/test"

<HeadContent>
     <meta name="description" content="Hello World">
</HeadContent>

Viewing the page in a browser will render the meta tags in the head as expected but doing a get request in insomnia/postman returns the initial headers and a blazor pre-render tag comment

<!--Blazor:{"sequence":0,"type":"server","prerenderId":"b0376004567c4aaf9c07defc4341e21e","descriptor":"<long string here>"}--><!--Blazor:{"prerenderId":"b0376004567c4aaf9c07defc4341e21e"}-->

Is this a bug or am I missing something? I need the head to be rendered before or with the rest of the page so search engines can pick it up.

Boor answered 24/10, 2021 at 11:28 Comment(0)
B
3

This was solved by moving the html/head/body from _Host.cshtml to _Layout.html. More info described in this post: https://github.com/dotnet/aspnetcore/issues/37293

Boor answered 1/11, 2021 at 19:31 Comment(2)
A comment from the link: "People creating their own application won't figure this out, nor be able to reason about why a more natural app structure doesn't work." - lol. Thankfully there is SO. +1Heartburn
I don't have _Layout.html, I have MainLayout.razor, but putting the suggested in there just destroys my layout.Pessary
E
0

I did not have a _Layout file. Rather than moving, I fully qualified HeadOutlet's class in the _Host file and got it working.

<component type="typeof(Microsoft.AspNetCore.Components.Web.HeadOutlet)" render-mode="ServerPrerendered" />
Estes answered 14/11, 2023 at 22:23 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.