Blazor WebAssembly Full Stack Bootcamp
Tags: beginners, webdev, dotnet, blazor
Published: 2020-10-15 14:35:07

---
title: Blazor WebAssembly Full Stack Bootcamp
published: true
description: Build an online browser game from scratch using Blazor WebAssembly, Web API, Entity Framework & SQLite in .NET.
tags: beginners, webdev, dotnet, blazor
series: Blazor WebAssembly Full Stack Bootcamp
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/m3539non1nzh8acubxr2.jpg
---

> This tutorial series is also available as an online video course. You can [watch it on YouTube](https://youtu.be/hnVh1yVmSAU) or [enroll on Udemy](https://www.udemy.com/course/blazor-webassembly/?referralCode=647B4EAACD6D8E4E6872). Or you just keep on reading. Enjoy! :)

{%youtube hnVh1yVmSAU %}

# Introduction

Blazor WebAssembly is turning the web development world upside down.

With Blazor you can keep coding every part of your web application - meaning front end **and** back end - with the programming language and the framework you love - **C# and .NET**.

**No need for JavaScript** anymore and you can even use the same classes and methods you write **for the server as well as for the client**.

In this tutorial series, we will dive right into the code by first having a look at the standard example project of Blazor WebAssembly and then we already build the main project of this tutorial series, which is a classic **online browser game**, where users can create an army of fighters and send them into battle against other users.

Together with some customization options and climbing the leaderboard, this application will teach you how to use Blazor WebAssembly with **Razor components** in a playful way.

We will have a look at **data binding and event handling**, **communication between components**, **forms** with their **built-in components** and **validation** options, how to use views only **authorized users** can see, how to make calls to a **web service**, and much more.

Additionally, you will learn how to build the back end of the browser game with a **Web API** and **Entity Framework** to store all the data in a **SQLite** database.

By the end of this tutorial series, you will have what it takes to **call yourself a full stack Blazor web developer**.

With your new skills, you are ready to **conquer any upcoming .NET web development project** you want to build yourself or any project that is requested by a recruiter.

Are you ready? Let's start!

## Tools

The only tools you need in the beginning are the [.NET SDK](https://dotnet.microsoft.com/download/visual-studio-sdks) and [Visual Studio](https://visualstudio.microsoft.com/vs/community/).

Depending on when you’re watching this course, you can choose to download the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download/visual-studio-sdks), the preview or release candidate of .NET 5 - which will combine .NET Core with the older .NET framework, or .NET 5 has already been released, then you’re safe to choose this SDK.

This course will use .NET Core 3.1 because, by the time of writing these lines, this version has been the latest stable release. So to be absolutely safe, please choose this version as well - but there shouldn’t be many differences between .NET Core and .NET 5 if any.

Regarding Visual Studio, you can use the [Community Edition of Visual Studio 2019](https://visualstudio.microsoft.com/vs/community/). It’s totally free and provides all the functions we need. If you decide to use a preview version of a .NET SDK, you probably also need a preview of Visual Studio. Just keep that in mind. Otherwise, the latest released version of Visual Studio is perfect.

If you already want to get the necessary tools for the back end, you can download and install [Postman](https://www.postman.com/), which we will use to test our web service calls later on. Sometimes it’s just nice to test a call to the Web API before you build the corresponding front end.

Additionally, you could already download the [DB Browser for SQLite](https://sqlitebrowser.org/), which enables you to, well, browse through a SQLite database.

But, again, these tools are used later in this tutorial series.

For now, please download and install the [.NET SDK](https://dotnet.microsoft.com/download/visual-studio-sdks) of your choice and [Visual Studio 2019 Community Edition](https://visualstudio.microsoft.com/vs/community/).

## Git Repository on GitHub

One last thing before we start with creating our Blazor WebAssembly project.

You can [get the complete code you’ll see during this tutorial series on GitHub](https://github.com/patrickgod/blazorbattles).

Here’s the link to the repository: https://github.com/patrickgod/blazorbattles

As you can see, the commits in this repository match the structure of this tutorial series.

![Git Commits](https://dev-to-uploads.s3.amazonaws.com/i/2g8lss0ca7g464cwpwge.png)

So if you’re struggling with your code, please have a look at this repository. I hope it helps to find a solution.

Or just grab the code and build your own browser game with it. Whatever you like.

Anyways, if you still have any problems with the code, you can also reach out to me, of course.

Now let’s create the project.

# Jumpstart

## Create an ASP.NET Core Hosted Blazor WebAssembly Project

Alright, when you start Visual Studio, choose *Create a new project* first.

![Create a new project](https://dev-to-uploads.s3.amazonaws.com/i/gy056rfl39dc58b7j1c8.png)

From the templates, we choose a *Blazor App*. If you can’t find it, just use the search bar on top and look for *blazor* for instance.

![Blazor App](https://dev-to-uploads.s3.amazonaws.com/i/uywgoilykyr19fnkcunc.png)

Let’s give this thing a suitable name like *BlazorBattles* for instance and click *Create*.

![Project name](https://dev-to-uploads.s3.amazonaws.com/i/60h1i4a94eiuvh00jf1h.png)

Now it’s getting interesting. We have a bunch of options available here.

First the .NET SDK version. I’d like to use .NET Core 3.1.

Then we can choose between a Blazor Server App and a Blazor WebAssembly App. Well, according to the title of this tutorial series, we should choose Blazor WebAssembly.

If you don’t know the difference, just real quick: A Blazor Server App runs completely on the server. There are no actual web service calls like you might be used to with a typical web application.

The description says that user interactions are handled over a SignalR connection, meaning over web sockets. So the user doesn’t really download the client app to the browser, which is great.

![Blazor Server vs. Blazor WebAssembly](https://dev-to-uploads.s3.amazonaws.com/i/xgbo73vw35s6srj2914p.png)

But the big disadvantage is that the server has to handle everything. So if your app has a lot of users, the server has to manage all the interactions of every user, all current states, and so on.

With a Blazor WebAssembly application, the server has a lot less to do, because the client handles the interactions which might be faster for the user - speaking of user experience and offline functionality, for instance - and which is the typical structure of a modern web application.

Maybe you have already built a web application with a .NET back end and a JavaScript framework like Angular, React, or VueJS for the front end. These frameworks handle user interactions as well and make web service calls to the back end.

With Blazor WebAssembly it is the same thing, but you don’t have to write JavaScript.

You can keep writing C# code and even use the same classes for the client and the server. I just love that fact.

So, long story short, we choose the Blazor WebAssembly App.

We don’t need authentication for now. We will implement authentication later by ourselves, which is a great way to learn.

Configure for HTTPS is fine and then comes an important checkbox, we select *ASP.NET Core hosted*.

![Configuration of new project](https://dev-to-uploads.s3.amazonaws.com/i/myw0mm0tpqsoz0jqthud.png)

With that selection, we already get a **server** project and a **shared** project additionally to our client project.

We’ll have a look at these projects in the next chapter. For now, it’s just important to know that this checkbox provides a solution where we can already make use of a Web API. So, a full-stack web application in one solution with C# and .NET only.

That’s it.

At the bottom right you can double-check the used .NET (Core) version and then click *Create*.

![Finally create the project](https://dev-to-uploads.s3.amazonaws.com/i/y6ce0x3uuslj8mpvrz68.png)

And there’s our new solution. Great!

Let’s open the Solution Explorer on the right and then see what has been created for us.

## Solution Overview

So, in the Solution Explorer of Visual Studio, you see three projects, Client, Server, and Shared.

![Solution Explorer](https://dev-to-uploads.s3.amazonaws.com/i/ujgtcwxppfj29rvde1r5.png)

The *Client* project represents the front end. Here’s where all the Blazor WebAssembly magic will happen.

The *Server* project will be the home of the Web API and Entity Framework.

And the *Shared* project will be used to share classes between the client and server projects. This means, building a model once and using it for both the client and the server. You can already see the WeatherForecast model here for instance, but we’ll talk about the example application in the next chapter.

Let’s have a look at the client project first.

The `Program.cs` file with the `Main()` method is the starting point. We will mainly use this method to register new services we write by ourselves or services that will be added by new packages.

```csharp
namespace BlazorBattles.Client
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("app");

            builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

            await builder.Build().RunAsync();
        }
    }
}
```

You can already see that something is happening here with the `HttpClient` class, and above that line, a root component is added, which would be the `App` component we can find in the `App.razor` file.

```html
<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>
```

A component in Blazor is a razor file. That's why it's also called a *Razor component*.

So the `App` component is the root component where you actually see the use of further components like the `Router`, the `Found` and `NotFound` component, and the `RouteView` for instance.

The `Router` component that wraps the other ones, in this case, decides if a route that has been entered in the address bar of the browser is correct or not.

If it is correct, the `Found` component will be used to display the content of the entered route, if not, the `NotFound` component will be used. Both components, in turn, use further components, a `RouteView` and a `LayoutView`.

And these two make use of the `MainLayout`. But let’s stick to the `LayoutView` first. It uses the `MainLayout`, but the content can already be seen here. It’s a simple text wrapped by a standard HTML paragraph tag.

```html
<LayoutView Layout="@typeof(MainLayout)">
    <p>Sorry, there's nothing at this address.</p>
</LayoutView>
```

The `RouteView` though uses the `MainLayout` but with the content of the actual page, the user wants to see by entering a particular route. And this page can be found in the `Pages` folder.

We’ll get to that in a second.

Let’s have a quick look at the `_Imports.razor` file. It’s quite simple, you will find global using directives here. That’s it. If you don’t want to add a reference in a single component, add it here instead.

```csharp
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using BlazorBattles.Client
@using BlazorBattles.Client.Shared
```

Okay, next, let’s have a look at the `MainLayout` in the `Shared` folder.

```html
@inherits LayoutComponentBase

<div class="sidebar">
    <NavMenu />
</div>

<div class="main">
    <div class="top-row px-4">
        <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
    </div>

    <div class="content px-4">
        @Body
    </div>
</div>
```

Looks like standard HTML at first glance, right?

Well, the only difference is that it inherits from the `LayoutComponentBase` class. And when you look at this class, you can see that it has a property called `Body` of type `RenderFragment` which is used in the `MainLayout` with `@Body`. And that’s where the pages will be rendered.

```csharp
namespace Microsoft.AspNetCore.Components
{
    //
    // Summary:
    //     Optional base class for components that represent a layout. Alternatively, components
    //     may implement Microsoft.AspNetCore.Components.IComponent directly and declare
    //     their own parameter named Microsoft.AspNetCore.Components.LayoutComponentBase.Body.
    public abstract class LayoutComponentBase : ComponentBase
    {
        protected LayoutComponentBase();

        //
        // Summary:
        //     Gets the content to be rendered inside the layout.
        [Parameter]
        public RenderFragment Body { get; set; }
    }
}
```

Additionally, you can see another used component, the `NavMenu`, but we’ll get to that soon.

Do you already see how these things work together?

A component can be used by *adding a tag with its exact name*. And any page will be rendered in the `@Body` part of a Layout.

You could build a custom layout if you like and use that one instead of the `MainLayout` in the `App.razor` component. Totally up to you.

Anyways, let’s have a look at the pages, for instance, the `Index.razor`.

```html
@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />
```

The crucial part is the `@page` directive with a string that already is the route for that page. You don’t have to specify that route anywhere else. Just create a component, add that `@page` directive, and you’re done.

```html
@page "/"
```

It’s the same with the `FetchData` and the `Counter` pages.

Before we have a deeper look at the code, a quick word about the other projects.

The server project first consists of a `Program.cs` and a `Startup.cs` file.

In the `Startup` class we find the `ConfigureServices()` and the `Configure()` method.

The `ConfigureServices()` configures the app’s services, so a reusable component that provides app functionality.

```csharp
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllersWithViews();
            services.AddRazorPages();
        }
```

We will *register* services in the future in this method, so they can be consumed in our web service via *dependency injection* for instance, similar to the `Program.cs` of the client project.

Please don’t mind all these buzzwords right now…

The `Configure()` method creates the server app’s request processing pipeline, meaning the method is used to specify how the app responds to HTTP requests.

```csharp
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseWebAssemblyDebugging();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseBlazorFrameworkFiles();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
                endpoints.MapControllers();
                endpoints.MapFallbackToFile("index.html");
            });
        }
```

As you can see we’re using `HttpRedirection`, `Routing`, and so on. With all these `Use...()` extension methods, we’re adding middleware components to the request pipeline. For instance `UseHttpRedirection()` adds middleware for redirecting HTTP requests to HTTPS.

Now the `Startup` class is specified when the app’s host is built. You see that in the `Program` class in the `CreateHostBuilder()` method. Here the `Startup` class is specified by calling the `UseStartup()` method.

```csharp
namespace BlazorBattles.Server
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}
```

Regarding the `appsettings.json` files we only need to know that we can add and modify some configurations here.

More interesting and often used throughout the back end part of this course is the `Controllers` folder.

![Controllers folder](https://dev-to-uploads.s3.amazonaws.com/i/mqlxbixul7fxbkb0td56.png)

The first controller you see here is the generated `WeatherForecast` demo controller. We’ll get to the details of controllers later. For now, it’s only important to know that we can already call the `Get()` method here which is actually done by the `FetchData` component.

```csharp
        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 7).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
```

I’d say, we do that next.

## Example Project Explained

Let’s run the application first and then talk about some files we haven’t talked about yet.

The great thing about Visual Studio and .NET Core hosted Blazor WebAssembly applications is that you can simply start this whole package with that little play button on top. Let’s do exactly that.

![Start application with play button](https://dev-to-uploads.s3.amazonaws.com/i/d7cng662qrqti7ielosa.gif)

The actual starting project is the *Server* project and Visual Studio will fire up IIS Express with a browser of your choice to start the app.

When you have a close look, you see the text “Loading…”. Where does that come from, you might ask?

![Loading...](https://dev-to-uploads.s3.amazonaws.com/i/5ntpq66e8kz9mlhn91ji.png)

Well, the client project has got this folder called `wwwroot` which is the root of the actual website, and here next to some cascading style sheets and a favicon you can find the actual `index.html`. And here you find the loading text.

```html
<app>Loading...</app>
```

Any resources you want to add later, like icons, images, other stylesheets, and so on, have to be added to this `wwwroot` folder. We will use this place later.

The crazy thing now is, that you can actually *debug the client and the server at the same time*.

You see, that the counter page increases a counter.

![Increase counter](https://dev-to-uploads.s3.amazonaws.com/i/33yy54r2zwe4oaexq6wr.gif)

Let’s have a look at the code.

```csharp
@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

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

@code {
    private int currentCount = 0;

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

It seems like there’s not much to see, but actually, there’s already happening a lot.

You already know the `@page` directive.

Then you can use the `@currentCount` variable.

```html
<p>Current count: @currentCount</p>
```

This integer variable can also be found in the `@code` block at the bottom.

```html
private int currentCount = 0;
```

So in this `@code` block, you’re free to write C# code and use that code above within your HTML code. With the `@currentCount` variable you already see how *data binding* is done in Blazor WebAssembly.

And in the button, you can already see *event handling*.

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

The `onclick` event, marked with an `@` calls the `IncrementCount()` method. Simple as that.

By the way, if you don’t like having your C# code together with HTML, you can create a code-behind file for your C# code instead.

Now let’s set a breakpoint inside the `IncreaseCount()` method.

![Breakpoint in IncreaseCount() method](https://dev-to-uploads.s3.amazonaws.com/i/s9kof888oyp2ggt8xeg3.gif) 

We hit the *Click me* button and hit the breakpoint. Crazy.

![Hitting the breakpoint](https://dev-to-uploads.s3.amazonaws.com/i/c0c3z8xmiqfgfpb3qapk.gif)

Now, what’s up with the service? Let’s have a look at the `FetchData` page.

This page actually makes a call to the Web API of the server project. We can see that in the network tab of the console.

![WeatherForecast call in network tab](https://dev-to-uploads.s3.amazonaws.com/i/wcewf53wn2ug2qh71o1r.gif)

Looking at the code, we see a lot of new stuff.

```csharp
@page "/fetchdata"
@using BlazorBattles.Shared
@inject HttpClient Http

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
    }

}
```

First the using directive. We’re referencing the `Shared` project here, because we’re using the `WeatherForecast` class.

Then we inject the HttpClient which enables us to make web service calls.

```csharp
@using BlazorBattles.Shared
@inject HttpClient Http
```

Inside the table, we see a `foreach` loop that uses the forecasts received from the service.

```csharp
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
```

We’ll do all this later by ourselves, so please don’t mind my pacing for now if it’s a bit too fast.

In the `@code` block we see a new method called `OnInitializedAsync()`. This thing is part of the **component lifecycle** and is called, as the name may imply, on the initialization of the component.

```csharp
    protected override async Task OnInitializedAsync()
    {
        forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
    }
```

And in this method we’re using the injected `HttpClient` to make a `Get()` call to the `WeatherForecast` route which would be the `WeatherForecastController` of the server project, which is, by the way, also using the `WeatherForecast` class of the `Shared` project.

Let’s move to that controller and set a breakpoint in the `Get()` method and then run the app again.

![WeatherForecast breakpoint](https://dev-to-uploads.s3.amazonaws.com/i/2u39kwcojurvyhf97t68.png)

When we open the `FetchData` page, the breakpoint in the service is hit. Fantastic!

![WeatherForecast breakpoint hit](https://dev-to-uploads.s3.amazonaws.com/i/f984r5ysuh0irljxxcwq.png)

Now, although being able to debug client and server at the same time is great, I like to run the application in another way.

Because with the way I just showed you, you have to stop and run the project by yourself every single time you made some changes to your code. This slows down development.

So instead, I like to use the *Package Manager Console* with the `dotnet watch run` command, which rebuilds the project when any code change has been recognized.

There's only one problem: So far this only works for the server project. If we make any changes to the client project, they won’t be recognized. But, of course, we can fix that.

In the project file of the server, we add a new ItemGroup.

```html
  <ItemGroup>
    <Watch Include="..\Client\**\*.razor" />
  </ItemGroup>
```

With that little change, the application notices any change happening in any `razor` file of the client project - additionally to any change in the server project.

Now let’s open the Package Manager Console and then first move to the directory of the server.

![Move to Server directory](https://dev-to-uploads.s3.amazonaws.com/i/5b5hfntwy164x0t21is0.jpg)

Now enter `dotnet watch run`. When the app is running, you already see the URL we have to enter in Chrome.

![dotnet watch run](https://dev-to-uploads.s3.amazonaws.com/i/ruhju2dglhuhcpk5l1yp.jpg)

This URL can also be found in the `launchSettings.json` files of your projects.

Now the breakpoints won’t be hit, but let’s increase the counter by 2 for instance.

```csharp
private void IncrementCount()
{
    currentCount += 2;
}
```

The change will be recognized, the app is rebuilt and we just have to reload the page to see the change.

![File changed](https://dev-to-uploads.s3.amazonaws.com/i/t22lx6nsfgmn2zkrja4h.png)

The same for the server. Let’s return seven forecasts instead of five and reload the page.

```csharp
	[HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 7).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
```

Now we see seven forecasts.

![Seven forecasts](https://dev-to-uploads.s3.amazonaws.com/i/yob14xw4r1uzdxau06y4.png)

You see, this makes developing your Blazor WebAssembly app a lot faster.

One thing we haven’t talked about yet is the `NavMenu`. But by now, you may already know how this component works.

You see some data binding and event handling with the `ToggleNavMenu()` function and the `NavMenuCssClass` variable.

```html
<div class="top-row pl-4 navbar navbar-dark">
    <a class="navbar-brand" href="">BlazorBattles</a>
    <button class="navbar-toggler" @onclick="ToggleNavMenu">
        <span class="navbar-toggler-icon"></span>
    </button>
</div>

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="counter">
                <span class="oi oi-plus" aria-hidden="true"></span> Counter
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="fetchdata">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
            </NavLink>
        </li>
    </ul>
</div>

@code {
    private bool collapseNavMenu = true;

    private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    private void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }
}
```

New though is the `NavLink` component. This is a **built-in component** for navigation links.

```html
            <NavLink class="nav-link" href="counter">
                <span class="oi oi-plus" aria-hidden="true"></span> Counter
            </NavLink>
```

The description already says it all: *It’s a component that renders an anchor tag, automatically toggling its `active` class based on whether its `href` matches the current URI*. And the `href` would be the string that is used with the `@page` directives of your pages. 

One last thing I want to show you in this example application is the first way of **communication between components**.

When we switch to the `Index.razor` again, you see the use of the `SurveyPrompt` component with a `Title`.

```html
<SurveyPrompt Title="How is Blazor working for you?" />
```

This `Title` is actually a **parameter**. So the parent component `Index` can tell the child component `SurveyPrompt` anything with the help of parameters.

Looking at the `SurveyPrompt` component, you see the `Title` property in the `@code` block, marked by a `[Parameter]` attribute.

```csharp
@code {
    // Demonstrates how a parent component can supply parameters
    [Parameter]
    public string Title { get; set; }
}
```

And then this `Title` - provided by the parent - is used in the HTML above.

```html
<strong>@Title</strong>
```

Alright, that should be it for the example application. Already a lot of input I guess.

Let’s make a new Git repository out of this and then start building our browser game with Blazor.

## Initialize Git Repository

To initialize a Git repository, on the bottom right of Visual Studio we click on *Add to Source Control* and choose *Git*.

![Add to source control](https://dev-to-uploads.s3.amazonaws.com/i/z0bzfy0orkesnrxqqlht.png)

And that’s it actually. Now we’ve got a **local repository** where we can commit our changes and have a history of them.

We could also publish this repository to any remote one or use GitHub or Azure DevOps, for instance. This could also be a private repository. So if you want to save your code to the cloud feel free to do so.

As mentioned earlier, you will [find the code of this tutorial series on GitHub](https://github.com/patrickgod/blazorbattles) as well. So if you have any trouble or just want to play around with the project, feel free to access this project on GitHub, clone the repo, fork it, star it, and so on.

Alright, that’s it for this part of the Blazor WebAssembly Full Stack Bootcamp. Let’s make a game next.

---

That's it for the first part of this tutorial series. I hope it already was useful to you. To get notified for the next part, simply follow me here on [dev.to](https://dev.to/_patrickgod) or [subscribe to my newsletter](https://mailchi.mp/3551dea75463/blazor). You'll be the first to know.

See you next time!

Take care.

---

*Next up: Your first Razor component, communication between components with parameters, event callbacks and services, create a new page, and more!*

<small><i>Thumbnail: vector illustration/Shutterstock</i></small>

---
### But wait, there’s more!
* Watch the [Blazor WebAssembly Full Stack Bootcamp online course](https://www.udemy.com/course/blazor-webassembly/?referralCode=647B4EAACD6D8E4E6872)
* [Subscribe to my newsletter](https://mailchi.mp/3551dea75463/blazor) for exclusive content
* Get the [5 Software Developer’s Career Hacks](http://patrickgod.com/5-software-developers-career-hacks/) for free.
* Let’s connect on [Twitter](https://twitter.com/_PatrickGod), [YouTube](https://www.youtube.com/channel/UCq8LldVrjqe61KQttZlLW8g), [LinkedIn](https://www.linkedin.com/in/patrickgod) or here on [dev.to](https://dev.to/_patrickgod).