Welcome to Rizzy

September 7, 20233 minutes

So it turns out Razor Components do a pretty good job as a replacement for Razor Views.

This project was started based off of my early experiences using Htmx with Razor Views and more specifically Razor View Components. Razor View Components are kind of like mini controllers and can be embedded inside of Razor Views using tag helpers. The syntax is fairly clumsy and there isn’t any support for nested child content. That was a bit rough to work with as HTML itself as a markup language utilizes nesting to great effect.

So how did we get here?

Most of the thanks for this whole project should go to the Blazor team who revamped Blazor SSR in a way that makes all of this possible.

Khalid Abuhakmeh has been an excellent advocate of using Asp.net with Htmx. He’s a developer advocate for Jetbrains and has published quite a few articles on various integration techniques between the two technologies. Khalid also has a nice library called Htmx.net that encapsulates the Request and Response header management that Htmx utilizes. While I’ve contributed to that library for Rizzy I worked with Egil Hansen who created the basis for Htmx Request/Response management. He wrote the Request code and I wrote all the Response management code.

Htmx.net also has some Tag Helpers which are useful to Views, but just won’t work with Razor Components and never will. As a result, much of his library couldn’t be used for Rizzy but there are still a lot of cool bells and whistles that come with the Rizzy implementation that wouldn’t have been possible if it integrated Htmx.net.

Rizzy was inspired by a lot of different projects, not all of them asp.net related. htmx-go, a type-safe library for working with HTMX in Go, provided inspiration for the fluent HTMX response Reswap modifiers.

ViewContext.Htmx.Response.Reswap(SwapStyle.InnerHTML
    .ShowOn("#dynamic-area", ScrollDirection.Top)
    .After(TimeSpan.FromMilliseconds(500)));
// Reswap output: "innerHTML show:#dynamic-area:top swap:500ms"

Alexander Zeitler created an awesome tag helper for Asp.net views that serialized POCO objects so they could be utilized within the Alpine.js x-data attribute. I created a variant of his tag helper that could be used within Razor Components as seen here.

  @using Rizzy.Extensions

  @code {
    var model = new MessageViewModel {
      Message = "Hello, Alpine.js!"
    };
  }
    <div x-data="@model.SerializeAsAlpineData()">
        <p x-text="message"></p>
        <button @click="message = 'Message updated!'">Update Message</button>
    </div>

Egil Hansen started a project called Htmxor that I contributed some code to but it didn’t get too far into development. Nonetheless, it had some excellent ideas for dealing with HTMX configuration that I extended to utilize the Options pattern for managing both default and named configurations. There is quite a bit of code from that project that exists as the starting core of Rizzy. In fact, a lot of ideas from Rizzy came from conversations with Egil. Egil is notable because of his work as a developer on bUnit, which is a testing library for Blazor components.

Along the way I had a few contributions of my own. I created a small HTMX extension that allows a developer to perform streaming rendering of Razor Components with HTMX. I also created an Htmx.Net Toast library to make it easy to integrate Toast messages with Asp.net Views.

And where are we going?

At the moment I’m kind of dog-fooding my own library as I work on a passion project of my own that has a pretty sizeable scope. As I go through the process it’s helping me discover pain points with Rizzy, which has been helpful to building up the library. At the moment I’d say the library is very much in active development and is at a point in time where the API should not be considered to be stable. There is a lot more to come, but I think this library should hopefully be useful to others who can join in and share ideas about the combination of technologies.