Introduction

Blazor is a web UI framework from Microsoft that allows .NET developers to build interactive web applications using C#, .NET, HTML, and CSS.

Instead of writing application logic primarily in JavaScript, developers can use C# and Razor components to create reusable user interfaces. Depending on the Blazor hosting model and application configuration, code can run in the browser, on the server, or be rendered interactively using modern ASP.NET Core capabilities.

In this article, we will create a simple Blazor application step by step and build an interactive counter component. Along the way, we will understand Razor components, event handling, data binding, project structure, and how the application works.

What Is Blazor?

Blazor is Microsoft's framework for building web user interfaces with .NET.

A Blazor application is built from components. A component typically contains:

For example, a button can call a C# method directly:

<button @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

When the user clicks the button, the IncrementCount method runs and the component updates its displayed state.

Blazor Hosting Models

Blazor has evolved with ASP.NET Core, so it is useful to understand the major hosting approaches.

Blazor WebAssembly

Blazor WebAssembly runs .NET code in the browser through WebAssembly.

The browser downloads the application and its required .NET runtime resources, after which supported application code can execute on the client.

This model is useful when an application requires substantial client-side execution.

Blazor Server

The original Blazor Server model executes components on the server. UI events are sent to the server and UI updates are communicated back to the browser over a real-time connection.

This reduces the amount of application code that needs to execute in the browser but requires a persistent connection between the client and server.

Blazor Web Apps

Modern ASP.NET Core also supports the Blazor Web App model, which allows developers to combine server-side rendering with interactive rendering modes.

This provides more flexibility when deciding which parts of an application need interactivity.

For new applications, the recommended project template depends on the .NET version and the application's requirements.

Prerequisites

Before creating the application, install the following:

You can verify the installed .NET SDK by running:

dotnet --version

The command should return the installed SDK version.

Creating Your First Blazor Application

There are several Blazor project templates available in modern .NET. The exact template options depend on the installed SDK version.

For a current Blazor Web App, you can create a project with:

dotnet new blazor -o BlazorDemoApp

Move into the project directory:

cd BlazorDemoApp

Then start the application:

dotnet run

The terminal will display the local address where the application is running.

Open that address in a browser to view the application.

Understanding the Project Structure

After creating the project, you will see several files and directories.

A typical Blazor project contains components, configuration files, static assets, and application startup code.

Some important areas include:

BlazorDemoApp
│
├── Components
│   ├── Layout
│   ├── Pages
│   └── App.razor
│
├── wwwroot
│
├── Program.cs
├── appsettings.json
└── BlazorDemoApp.csproj

The exact structure can vary between .NET versions and project templates.

Components

The Components directory contains Razor components used to build the application's user interface.

Pages

Application pages are implemented as Razor components and can be associated with routes.

For example:

@page "/counter"

This makes the component available at the /counter route.

wwwroot

The wwwroot directory contains static web assets such as:

Program.cs

Program.cs is responsible for application startup and service configuration.

In a Blazor Web App, it also configures the Razor component infrastructure and the application's HTTP pipeline.

Creating an Interactive Counter Component

Now let's build a simple interactive component.

Create or open a Razor component such as:

Components/Pages/Counter.razor

Add the following code:

@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">
    Click me
</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

This example contains the main concepts of a basic Blazor component.

Understanding the Counter Code

The @page Directive

The following line defines the route:

@page "/counter"

When the application is configured for routing, navigating to /counter displays this component.

Displaying C# Data in HTML

The following markup displays the value of a C# variable:

<p role="status">Current count: @currentCount</p>

The @ symbol allows Razor syntax to transition from HTML markup to C# expressions.

Initially, currentCount is 0.

After the value changes, Blazor updates the relevant part of the UI.

Handling Button Clicks

The button uses:

@onclick="IncrementCount"

This connects the button's click event to the C# method:

private void IncrementCount()
{
    currentCount++;
}

Every time the user clicks the button, the value increases by one.

Expected Output

When the /counter page is opened, the initial screen displays something similar to:

Counter

Current count: 0

[ Click me ]

After clicking the button once:

Counter

Current count: 1

[ Click me ]

After clicking it three more times:

Counter

Current count: 4

[ Click me ]

The important point is that no separate JavaScript function is required for this basic interaction. The event is handled by C# within the Razor component.

Adding a Reset Button

We can extend the component by adding another C# method.

@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">
    Increment
</button>

<button class="btn btn-secondary" @onclick="ResetCount">
    Reset
</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }

    private void ResetCount()
    {
        currentCount = 0;
    }
}

Now the component has two user actions.

Increment
    |
    v
currentCount++
    |
    v
Updated UI

Reset
    |
    v
currentCount = 0
    |
    v
Updated UI

Understanding Component State

The currentCount variable represents component state.

private int currentCount = 0;

When an event changes the state, Blazor can render the component again so that the UI reflects the new value.

This state-driven approach is one of the important concepts behind component-based UI development.

For example:

Initial State
currentCount = 0
       |
       v
User clicks button
       |
       v
currentCount = 1
       |
       v
Component renders updated UI

Passing Data to a Component

Blazor components can also receive data from a parent component through parameters.

For example:

<h3>Hello, @Name!</h3>

@code {
    [Parameter]
    public string Name { get; set; } = string.Empty;
}

A parent component can provide the value:

<WelcomeMessage Name="Baibhav" />

The component then receives the value through its Name parameter.

This allows components to be reused with different data.

Creating a Reusable Component

One advantage of component-based development is reusability.

Suppose we create:

Components/Shared/WelcomeMessage.razor

with:

<div class="alert alert-info">
    <h3>Welcome, @Name!</h3>
</div>

@code {
    [Parameter]
    public string Name { get; set; } = string.Empty;
}

The component can then be reused:

<WelcomeMessage Name="John" />
<WelcomeMessage Name="Sarah" />
<WelcomeMessage Name="David" />

The same component structure is used for all three users while the displayed value changes.

Data Binding in Blazor

Blazor also supports two-way data binding with the @bind directive.

For example:

<input @bind="name" />

<p>Hello, @name</p>

@code {
    private string name = string.Empty;
}

When the user enters a value in the input field, the name variable is updated through the binding mechanism.

For example:

Input:
[ Khan ]

Output:
Hello, Khan

This is useful for forms, search fields, filters, and other interactive components.

Why Use Blazor?

Blazor can be a good choice for organizations and developers already working with the .NET ecosystem.

Some of its advantages include:

Blazor does not mean that JavaScript disappears from every application. JavaScript can still be used when browser APIs, existing JavaScript libraries, or third-party integrations require it.

Blazor and JavaScript

Blazor is designed to allow .NET developers to build interactive web UIs with C#, but JavaScript remains part of the web platform.

For example, an application may use JavaScript interoperability when it needs to call a browser API or an existing JavaScript library.

Blazor provides JavaScript interoperability through mechanisms commonly referred to as JS interop.

Therefore, the practical difference is not simply:

Blazor = No JavaScript

A more accurate description is:

Blazor = Build interactive UI primarily with .NET and C#
          +
        Use JavaScript when the application requires it

Common Beginner Mistakes

Using an Outdated Project Command

Blazor templates and hosting models have changed across .NET releases. A command that worked with an older .NET version may not represent the recommended project structure for a current application.

Always check the template available in the installed SDK:

dotnet new list blazor

Putting Too Much Code in One Component

Components should have a clear responsibility. Large components become difficult to understand and maintain.

When a UI section becomes complex, consider extracting it into a reusable component.

Confusing Component State and Application State

A private field inside a component is suitable for local component state, but shared application state may require a different design.

Do not put all application data into a single component simply because it is easy to access.

Assuming JavaScript Is Never Required

Blazor reduces the need to write JavaScript for many UI scenarios, but browser applications can still require JavaScript interoperability.

A Simple Blazor Development Workflow

A beginner can follow this workflow when starting a Blazor project:

Create Project
      |
      v
Create Razor Component
      |
      v
Add HTML Markup
      |
      v
Add C# State
      |
      v
Handle User Events
      |
      v
Run Application
      |
      v
Test in Browser
      |
      v
Extract Reusable Components

This approach helps developers learn the framework without introducing unnecessary complexity.

Conclusion

Blazor provides a way to build interactive web interfaces using C#, .NET, Razor syntax, and reusable components.

In this tutorial, we created a Blazor application, examined its project structure, built an interactive counter, handled button events, worked with component state, created reusable components, and explored data binding.

The key concept to remember is that a Blazor application is built from components. Each component can contain markup, state, parameters, and event-handling logic, making it possible to create interactive web interfaces while staying within the .NET development ecosystem.

Once these fundamentals are understood, the next steps are to explore forms and validation, dependency injection, routing, authentication and authorization, API integration, component lifecycle methods, and application state management.