CshtmlComponent V3.0.0 - Head and Body Content Injection
Tags: aspnetcore, dotnet, csharp, webdev
Published: 2020-10-11 05:46:04

[CshtmlComponent](https://cshtml-component.acmion.com) 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](https://cshtml-component.acmion.com).

## 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](https://cshtml-component.acmion.com) 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](https://github.com/Acmion/CshtmlComponent).

Happy hacking with CshtmlComponent!