The Practical Client

Adding Blazor to Existing HTML+JavaScript Pages

If you're thinking about Blazor at all, you have to be wondering if it's possible to integrate Blazor into existing pages. The current state of Blazor suggests that it's possible to integrate JavaScript and Blazor to either move a site incrementally to Blazor or even incrementally move individual pages from JavaScript to Blazor. This allows you to not only add new functionality to a page in Blazor but also to selectively replace functionality created in JavaScript with C# code where it makes sense (or even to create common Blazor code and share it among pages).

I say "suggest" because Blazor is an 'experimental' technology and all its releases are marked as alpha -- much that's possible now may turn out to be impossible in a final, production-ready, reliable version of the technology.

You can create a Blazor application right now in Visual Studio 2017 (version 15.8 or later with .Net Core 2.1 2.1 v2.1.403 installed) using Blazor Language Services 0.6.0.

With Visual Studio's default Blazor projects, when you run a Blazor project you initially open an HTML page (index.html) which loads Blazor and then transfers control to a Blazor page (index.cshtml). You can have JavaScript code in the .html file you went through on the way to the .cshtml file but not in the .cshtml file that is sent to the user. However, the JavaScript in the .html has access to the HTML elements defined in the .cshtml page. The primary restriction on that JavaScript code is that it should not change the structure of the page's HTML by adding or removing elements -- that interferes with Blazor's representation of the page.

Initializing HTML and Blazor
This means that your first step in moving an existing HTML+JavaScript page to Blazor begins with putting your page's HTML in a .cshtml file while leaving your JavaScript in the related .html file.

Following this plan, an .html file might consist of some combination of the basic HTML skeleton elements (the html and body elements), script elements to load any required JavaScript files, a script tag that loads Blazor, and the JavaScript from the original page.

A typical .html file that references jQuery and opens a script element might look like this:

<!DOCTYPE html>
<html>
<head>
    <title>BlazorAndJS2</title>
    <base href="/" />
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
    <script src="_framework/blazor.webassembly.js"></script>
    <script>
      ...the page's JavaScript functions...

In a typical HTML+JavaScript page, processing begins with jQuery's ready function, which calls functions that initialize the page. To create a Blazor-enabled version of the page (and to make as few changes as possible) all you need to do is wrap that method in another function and call that function from your Blazor code.

Following that plan, the start of the script block in the .file page might look like the following code. As an example, I've included sample code that wires up a JavaScript function to the click event of an HTML button, now defined in the .cshtml file:

function InitPage() 
{
  $(function () 
  {
    $("#mybutton").click(function () 
    {
      ...code to execute on a button click...
    });
  });
}

In the .cshtml file, probably the best place to call that JavaScript code is from Blazor's OnAfterRenderAsync method, which is automatically invoked when Blazor has finished rendering the page. Below is a simple .cshmtl page with just the HTML for the button referenced from my JavaScript code. Following the HTML is an OnAfterRenderSysnc method that calls my JavaScript InitPage function (I've covered the JSRuntime's InvokeAsync method in more detail in an earlier column):

@page "/"

<input type="button" id="mybutton" value="click me" />

protected async override Task OnAfterRenderAsync()
{
  base.OnAfterRender();
  await JSRuntime.Current.InvokeAsync<object>("InitPage");
}

Your existing JavaScript code should now, probably, interact with your HTML as before (I did mention that Blazor is "experimental" technology in alpha release, right?). More importantly, you're now positioned to either extend this page or replace its existing JavaScript code with C# code. Either approach is probably going to require more integration between existing JavaScript and C# than what I've outlined here ... and, perhaps, a more architectural approach to structuring your Blazor code. I'll cover the architectural approach to handling that problem in my next column.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • How to Unlock Visual Studio 2022's Preview Features Like Claude Sonnet 3.7 AI Model

    Some developers complained that advanced AI models come sooner to VS Code than Visual Studio, but the new Claude Sonnet 3.7 model is now available in IDE with a paid GitHub Copilot account and a simple settings tweak in GitHub.

  • Semantic Kernel Agent Framework Graduates to Release Candidate

    With agentic AI now firmly established as a key component of modern software development, Microsoft graduated its Semantic Kernel Agent Framework to Release Candidate 1 status.

  • TypeScript 5.8 Improves Type Checking, Conditional Feature Delayed to 5.9

    Microsoft shipped TypeScript 5.8 with improved type checking in some scenarios, but thorny problems caused the dev team to delay related work to the next release.

  • Poisson Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demo of Poisson regression, where the goal is to predict a count of things arriving, such as the number of telephone calls received in a 10-minute interval at a call center. When your source data is close to mathematically Poisson distributed, Poisson regression is simple and effective.

  • Cloud-Focused .NET Aspire 9.1 Released

    Along with .NET 10 Preview 1, Microsoft released.NET Aspire 9.1, the latest update to its opinionated, cloud-ready stack for building resilient, observable, and configurable cloud-native applications with .NET.

Subscribe on YouTube

Upcoming Training Events