.NET6 Blazor Server预渲染应用HeadOutlet晚于App渲染问题
这不是框架Bug,是服务端预渲染的执行顺序逻辑导致的:
你当前根页面的组件渲染顺序是先执行HeadOutlet渲染,再执行App组件渲染。服务端预渲染阶段,HeadContent的内容是在对应页面组件(也就是你的Test页面)被渲染的时候才会注册到上下文,先渲染HeadOutlet的时候页面组件还没加载,拿不到对应的头部内容,只能输出占位注释。只有等到客户端Hydration完成后,头部内容才会被前端补全,所以爬虫抓预渲染的原始HTML时就获取不到自定义头部。
解决方案
修改根页面的预渲染逻辑,先预渲染App组件收集HeadContent内容,再渲染HeadOutlet:
@page "/" @namespace Example.Pages @using Microsoft.AspNetCore.Components.Web @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{ Layout = null; // 先预渲染App组件,提前收集所有HeadContent内容 var appRenderResult = await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered); } <!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> @* 直接输出提前预渲染好的App内容 *@ @appRenderResult <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>
修改完成后,服务端预渲染时会先执行App组件的渲染逻辑,此时Test页面的HeadContent会被注册到上下文,再渲染HeadOutlet时就能正确输出对应的meta标签,用Postman/Insomnia请求就能直接在返回的HTML中看到完整的头部内容,搜索引擎可正常抓取。
内容的提问来源于stack exchange,提问作者user3713080
相关产品推荐
相关产品推荐

