Skip to content

DynamicComponent renders outside of surrounding HTML tags after prerendering + hydration (render article from database and parsing markers) #61760

Open
@witM

Description

@witM

When using DynamicComponent to render custom components inside parsed article content (with Blazor Server prerendering enabled), the component renders outside of surrounding HTML elements like

or

— even though the HTML structure is valid during prerendering (I've checked this with disabled interactive rendering on the page) and verified with MarkupString fragments.

This is a fragment of Article.razor page where article is parsing and rendering. Article is stored in database as html string.

@foreach (var fragment in _fragments)
{
    switch (fragment)
    {
        case HtmlFragment html:
            @((MarkupString)html.Html)
            break;

        case ComponentFragment component:
            <DynamicComponent Type="Type.GetType(component.Name)" Parameters="component.Parameters" />
            break;
    }
}

_fragments is the result of article parsing, for example:

<p>This is a test: [[[Link ArticleName="Test"]]]</p>

After parsing this is split into 3 fragments:

  1. <p>This is a test:
  2. "[[[Link ArticleName="Test"]]]" --> rendering as DynamicComponent -> render <a href="..."></a> tag with custom logic
  3. </p>

The resulting prerendered HTML is correct, e.g.:

<p>This is a test:
  <a href="/test">Test</a>
</p>

But in browser (after hydration), the component renders outside the <p>:

<p>This is a test:</p>
<a href="/test">Test</a>
  • This only happens after hydration in Blazor Server that I'm writing the project
  • This makes it very difficult to parse HTML+components together safely (e.g. for CMS articles).

This a problem for any tag like

. I have for now two more "markers" [[[...]]] that are parsing and render as proper component, for example video player and it is interactive component. There is no problem with that component because I put the marker for it as just [[[VideoItem Name=".."]]] with no surrounding tags. The thing is some component have to be renders in some surrounding tags for UI experience and proper article styling just as aboe with the link example. For now this to work I use workaround like registered custom elements, but this is not the way to go for SEO purpose.

You can see all this in action on my website with example article rendering with video component (PL) : https://www.infomaks.pl/post/s_liczby_rzeczywiste/r%C3%B3wnanie_kwadratowe

Expected Behavior
DynamicComponent rendered inline with HTML via parsed fragments should maintain correct DOM hierarchy after hydration, just like during prerendering.

Environment

  • NET 9
  • Blazor Server app
  • Prerendering enabled and Interactive render set on component because of handling complex application state
  • Visual Studio 2022 preview 5

Suggested Feature / Fix

  • Adding special configuration in program.cs file setting how fragments are rendering during hydration. (example: warning not unclosed tag)
  • Consider partial hydration boundaries per component.
  • Adding by blazor one top surrounding tag during rendering and hydration on render fragment, dynamic component?

Repro project
Based on the official blazor template project:
https://github.com/witM/BlazorIssue/tree/main/BlazorArticleRender
See article page to see what's going on.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions