Basic tag helpers creation cheat sheet

Here is another tag helper cheat sheet, this time it is about creating simple custom tag helpers.

Again this document is not suitable for absolute beginners, so if you are seeking to understand tag helper creation forthe first time I would recommend the following articles:

The full code is available on Github if you want to build, run and hack the examples in this document.

Super simple hello world tag helper

Tag helpers are represented by a C# class that inherits the TagHelper abstract class or implements the ITagHelper interface.

The TagHelper.Process method or its async equivalent TagHelper.ProcessAsync is typically overitten to contain the rendering logic.

The content that will substitute the tag helper is written into the output argument.

The previous SimpleTagHelper will be substituted by <p>Very simple!</p> and can be used as follows:

Controlling the naming of the tag helper

You will notice that often times the tag helper C# class name ends with "TagHelper", this is actually a convention and is not mandatory.

The default html name of the tag helper is the class's name kebab cased with the "TagHelper" postfix removed, for example:

  • SimpleTagHelper becomes simple
  • SuperSimpleTagHelper becomes super-simple
  • LonglyNamed (postfix optional) becomes longly-named

The name of the tag helper can be controlled with the [HtmlTargetElement("some-name")] attribute:

The html element represented by the previous class is <arbitrary-name></arbitrary-name>.

It is possible to provide a pascal cased custom name such as [HtmlTargetElement("SomeName")], but please stick with the convention.

Tag helper as empty html element

It is possible to specify that a tag helper is an empty html element by using the TagStructure property in the [HtmlTargetElement] attribute, make sure to specify an explicit name otherwise the tag helper will target any custom tag helper.

Unfortunately, it seems that it is not possible to render regular html elements (with end and start tag) from an empty tag helper.

Tag helper activated by attribute

Tag helper can target standard html elements that have a user(developer) defined attribute, for example:

It is possible to create a tag helper that act on any element having the hello-prefix attribute, by using the Attributes property in the [HtmlTargetElement] attribute the following tag helper prepends the "Hello " string to the content of targeted elements.

Tag helper activated on standard html element

Again, by using the [HtmlTargetElement] attribute it is possible to target directly standard html elements by simply providing the name of the html element to the [HtmlTargetElement] attribute.

The previous tag helper erases the content of any <p> element present in cshtml views that includes it.

Pay attention to possible conflicts

When defining multiple tag helpers that targets the same standard html elements, you have to pay attention to possible conflicts since that the last tag helpers applied can erase the content rendred by the previous tag helper.

The solution in these cases is to check inside the Process method if the html elements content has been modified and, if so, to get the modified content from output.Content instead of output.GetChildContentAsync() as in the following example.

Furthermore, it is possible to control the order in which the tag helpers are executed by defining the Order readonly (get) property in the custom tag helper class. The smallest order as the priority.

Passing arguments to the tag helper

It is naturally possible to define custom attributes on a tag helper and use these attributes to pass data, consider this example:

Notice how the <with-arguments> tag helpers can accept variables, string literals and even C# expressions.

Argument placeholder are simply defined as properties in the tag helper class.

Similar to the tag helper's html element name, the Pascal cased property names are by default kebab cased on the cshtml side.

The [HtmlAttributeName] attribute can be used to specify a custom name.

Creating the tag helper's output content

Inside the Process method you typically populate the output argument with actual output content. Here are some actions performed in this regard.

  • Define the output tag name
  • Manipulate attributes on the output tag
  • Get the initial html content
  • Use interpolated strings to render the content