We want to use Blazor app as normal web app which has to be SEO friendly. We also want to integrate this app with social sites. To achieve this we have to dynamically build <head> section of html page. We have to have different title, description and metatags for each page.
We have prerendering already and main index.html file is now index.cshtml (at least in Blazor server side). One thing is missing. I would like to have some data structure (I want to define it myself) which is accessible to this main index.cshtml file and to all page files. You should make some magic and run prerendering logic first and then render the main index.cshtml file. With this functionality in place each page will be able to assign required information to fields in the data structure and then main html output will be correctly generated by index.cshtml.
This is critical if we want to have proper SEO and integration with social sites.
In terms of the order of execution, it's problematic to do this by declaring this data inside your components. They don't start executing until the part of your page above them has already been output, which presumably is too late based on what you're trying to do (add extra tags to <head>?).
I would recommend you create your own separate way of establishing what the correct metadata is for each given URL, so this logic can be executed independently of rendering components. For example, you could implement some ASP.NET Core middleware that acquires whatever metadata you want based on the URL (even depending on DB queries, etc., if you want), and then stash that information in something like HttpContext. Then you can access the same information both during the execution of your Razor Pages and during the prerendering of your components.
Thank you Steve for your suggestion. It is a little inconvenient to separate this logic from pages (especially when we think about performance and additional DB queries) but on the other hand it is good to set title, description and meta elements in one place. Now I have to wait for this: https://github.com/aspnet/AspNetCore.Docs/issues/11366
Here's a free and useful tool which DevExpress has made to help solve this issue: https://community.devexpress.com/blogs/aspnet/archive/2019/07/17/devexpress-blazor-update-metadata-at-runtime-free-seo-tool.aspx
I haven't tested this yet but it probably solves almost all problems except one: in multilingual site we have to change language in html element:
<html lang="en">
<html lang="pl">
...
Because I want to use url segments as "source of truth" for language/culture (for example: example.com/en-us/my-page) I hope I will be able to easily use this information in _Host.razor during prerendering. To implement this on the client (Web Assembly) I will try to use setAttribute in JavaScript.
<html lang="..."> will help the browser know the language of the response (just metadata) but it has no effect on anything happens in client or server-side Blazor. See: https://github.com/aspnet/AspNetCore.Docs/issues/13436
Do you plan to do this in Blazor itself? https://community.devexpress.com/blogs/aspnet/archive/2019/07/17/devexpress-blazor-update-metadata-at-runtime- 褋胁芯斜芯写薪褘泄 褋械芯-tool.aspx
Most helpful comment
Here's a free and useful tool which DevExpress has made to help solve this issue: https://community.devexpress.com/blogs/aspnet/archive/2019/07/17/devexpress-blazor-update-metadata-at-runtime-free-seo-tool.aspx