dotnet / dotnet/aspnetcore

Introduce new Tag Helpers to allow controlling output of head and body targeting ITagHelperComponents

Open
#48,313 1 comment 0 reactions 0 assignees View on GitHub
area-mvc feature-tag-helpers
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

Currently, the `` and `` tags in all Razor Views/Pages are Tag Helper activated (via the `HeadTagHelper` and `BodyTagHelper` respectively) so that any registered `ITagHelperComponent`s can easily emit content into the `` and/or `` tags.

This has a couple of unfortunate side effects, as Tag Helper activated tags cannot contain `FlushAsync` calls due to the way Tag Helper activated tag bodies are rendered. A runtime exception is thrown if this is attempted:

> InvalidOperationException: The FlushAsync operation cannot be performed while inside a writing scope in '/Pages/Shared/_Layout.cshtml'.

This prevents performing pre-emptive and incremental flushing inside the `` and `` tags, which can be a desirable optimization to improve TTFB and perceived performance in the browser.

It also prevents more precisely controlling where the output from `ITagHelperComponents` targeting the `` and `` tags is rendered.

To resolve these issues, we can introduce a new Tag Helper, inspired by the design of the Blazor "outlet" components, that would easily enable controlling exactly where the outlet of `ITagHelperComponents` is rendered.

Following is an example of how this might be used in a page. The built-in `HeadTagHelper` and `BodyTagHelper` are removed (as they're added by default) and then the new `` Tag Helper is used to control where content from `ITagHelperComponent` instances is rendered. The `` Tag Helper supports overriding the tag name that will be on the `TagHelperContext` passed to the `ITagHelperComponent` instances to allow easily controlling where the content for `ITagHelperComponent` instances targeting specific tag names is rendered.

```cshtml
@removeTagHelper "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor"
@removeTagHelper "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor"

@ViewData["Title"] - Example Site

...

...

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.