DEV Community

Acmion
Acmion

Posted on

CshtmlComponent V3.0.0 - Head and Body Content Injection

CshtmlComponent is a component framework for ASP.NET Core Razor Pages and MVC projects. The feature set is extensive and a significant improvement over alternatives. Not for Blazor.

V3.0.0

The main feature of V3.0.0 is that you can now directly inject content in both the head and body elements once per component. This is especially useful in cases where components require extra functionality provided by CSS or JS files.

The developer may choose whether to prepend or append content to either tag.

Previous Method

Referencing CSS or JS files was previously also possible, via the usage of CshtmlInitial, which renders some content once per page. The definitions of components that rely on this could have looked like this:

@* Reference the associated component as model. *@
@using SampleRazorPagesApplication
@model ExampleComponent

<CshtmlInitial>
    <link rel="stylesheet" href="/style.css" />
</CshtmlInitial>

<!-- The content of the component. -->
<div class="example-component">
    <h1>
        ExampleComponent: @Model.Title
    </h1>

    <div class="example-component-child-content">
        <!-- Render the child content. -->
        @Html.Raw(Model.ChildContent)
    </div>
</div>

However, while CshtmlInitial gets the job done (the content of the tag is only rendered once per page), the problem with this approach is that CshtmlInitial will render the content wherever the component is first instantiated.

New Method

With V3.0.0 we can instead utilize CshtmlHead or CshtmlBody, which both render their respective contents once per page (unless otherwise configured). The component definition would now look like this:

@* Reference the associated component as model. *@
@using SampleRazorPagesApplication
@model ExampleComponent

<CshtmlHead>
    <link rel="stylesheet" href="/style.css" />
</CshtmlHead>

<!-- The content of the component. -->
<div class="example-component">
    <h1>
        ExampleComponent: @Model.Title
    </h1>

    <div class="example-component-child-content">
        <!-- Render the child content. -->
        @Html.Raw(Model.ChildContent)
    </div>
</div>

Now the content within CshtmlHead would be injected in to the head element and the DOM would remain clean.

Additional Benefits of the New Method

The new method brings additional benefits as well. For example, one may configure the ordering and render the content more than once if appropriate. The configurations are relatively complex, please view them at the official documentation.

The Future of CshtmlInitial

CshtmlInitial has not and will not be deprecated (at least in the near future). It was even improved in this update! Previously, an extra Context attribute had to be specified. This attribute has now been removed, without affecting behavior, and has resulted in cleaner code.

Closing Statement

The documentation of CshtmlComponent was also revised to account for these new changes. Hopefully the documentation covers both old and new features better than before.

View the GitHub repository of CshtmlComponent here.

Happy hacking with CshtmlComponent!

Top comments (0)