Skip to content
Home » Blazor – My Portfolio – Part 3 – Razor Components

Blazor – My Portfolio – Part 3 – Razor Components

Spread the love

In the previous part of the series we created our My Portfolio project and we had a look at the sample code that we got out of the box. One of the pages that was created for us was the Counter page, so we had an opportunity to see what a Razor component looks like. But now it’s time to create the components that we are actually going to need in our project. So, let’s think about the components that we are going to need first. But even before that, let’s try to answer the question: What is a component in the first place?

What Is a Razor Component? 

A Razor component, also known as Blazor component, is the basic building block of a Blazor application. It combines a unit of UI with its corresponding unit of logic. The UI is created using Razor, the logic is implemented in C#.

A component may be of any size. It may consist of a single string, it may contain an image, some text and a button for example, but it may also be the whole page.

Components are reusable. Let’s take the Counter component that was created for us as the example. You already saw it in action, but now let’s try to add this component in some other locations. It’s as simple as adding the appropriate tag in Razor.

So, let’s do it. Open the Index.razor file and add a Counter component at the bottom like this:

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

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

<Counter />

Run the app and you will see the counter at the bottom of the page:

Go ahead and click the button several times. It works perfectly.

Now, before we go on adding more counters, I’d like to tell you about a feature of Visual Studio that will make your life a whole lot easier.

Hot Reload

The feature is called Hot Reload and it enables you to see the UI changes live while the application is running. Whenever you change something in the Razor code and save, the change will be reflected in your running app without having to stop and restart it.

Hot Reload should be activated by default. If it’s not, you can activate it yourself over here:

The option is available when the app is running. And now let’s see it in action. Make sure your app is running and add another counter, just below the first one:

@page "/"

...

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

<Counter />

<Counter />

If you now save the file, the second counter will immediately show up in your app:

If you click the buttons of each counter, you will see that they work independently.

And now let’s get rid of the SurveyPrompt component, we don’t need it anymore. Also, modify the texts on the page slightly. Your code should look like this:

@page "/"

<PageTitle>Index</PageTitle>

<h1>My Projects</h1>

Here are my projects.

<Counter />

<Counter />

Save the changes and they will be reflected in your running app:

And now let’s go back to our main topic, Razor components.

Nested Components

As you can see in the example above, components can be nested. Here the Counter component is nested in the Index.razor page, which itself is a component, but there may be as many levels of nesting as you need. We will see examples of that when we work on our project.

Invisible Components

Although most components contain moth presentation (UI) and logic (implemented in C# code), there are also components that lack one of these elements. It’s easy to imagine a component without logic. A component that only displays some text or an image doesn’t require any logic because it doesn’t do anything.

But what about components that have only logic and no visual representation? Well, in such cases the components are usually created in C# and they implement the IComponent interface. An example of such a component is the Router component that we use for navigation. You will find it in the App.razor file:

<Router AppAssembly="@typeof(App).Assembly">
    ...
</Router>

But you don’t have to worry about it too much. It’s just good to know J

Types of Components

We already touched upon this topic in the previous part of the series, but let’s briefly recap. There are three basic component types:

1) Independent (or navigable) components – these are the ones with the @page directive in the directives section at the top. They can be used on their own and not within another component. We usually refer to them as pages.

2) Dependent (or non-navigable) components – these are components without the @page directive. You can’t navigate to them and they must be embedded inside other components.

3) Layout components, or just layouts – these are components that inherit from the LayoutComponentBase class and are used to create layouts for multiple pages or the whole website.

There’s one thing worth clarifying here. Blazor applications are single-page applications (SPA applications for short), which means there is actually only one page and you don’t need a server to request another page. What we call pages in Blazor are actually components, not pages in the traditional sense, so we still have just one page and its content is replaced by new content, which is just another independent component.

The Components We’re Gonna Need 

Before we create our components, let’s think about what components we need for our app. Well, we’re going to need the following components:

Project and ProjectDetails – As this is a portfolio app, I want to show off my projects. We need a component to represent a single project. Actually, we need two. The Project component will display just a summary of the project. It’ll be a dependent component. The ProjectDetails component will be an independent component and you will navigate to it when you click on the Project component. The ProjectDetails component will contain all the information about the project.

ProjectDisplay, ProjectsByCategory and ProjectsByTech – These components will be used to display multiple Project components. The first one will be used to display any group of projects that we specify. The other two will be used to display the projects sorted by category or technology.

CategoriesMenu, TechsMenu and SocialMenu – These components will be used in the sidebar. The first two ones will be used to sort the projects by category or technology and they will be scrollable. The last one will just display links to my blogs and YouTube channels and contact information.

So, now that we know what we need, let’s create the components. For now we’ll just hard-code some information in them. The actual content will later come from a json file when we learn how to bind data, and so on. As we proceed, we’ll learn the Razor syntax as well.

Let’s start with the Project component.

The Project Component

We usually create independent components in the Pages folder and dependent ones in the Shared folder or in any other folder you create for that purpose. It may be called Components or whatever. For simplicity’s sake let’s put all the dependent components in the Shared folder.

So, right-click the Shared folder in the Solution Explorer, select Add, then Razor Component… and in the dialog that opens set the name of the component to Project.razor. By the way, the names of components must be capitalized. Hit the Add button and the component will be created for you. It will also automatically open in the editor. The default code it contains should look like this:

<h3>Project</h3>

@code {

}

So, the directives section is empty. In particular, we don’t have the @page directive because we shouldn’t be able to navigate to this component. We will put something in this section a bit later. The Razor section contains just an HTML h3 header. The code section is empty.

The component should contain an image, the name of the project, the icons representing the technologies used in it, a short description, info icons about where you can find stuff related to this project (like the code on Github, a video on Youtube, an article in a blog, etc.) and a link to the details page for that project. For now we’ll keep things simple and use text instead of the icons. We’ll replace the text with the icons a bit later.

We’re not going to need any code for now, but we can leave the code section because we are going to need some code eventually.

So, with that in mind, let’s get to work. We’ll need an image for our component. Let’s create an images folder inside the wwwroot folder (where all the static files will be placed) and copy an image there. I’m going to copy the image that I’ll later use for my Unity game project, Forest Monsters. If you’re creating the app for your portfolio, just put any image you like in the images folder. But if you’re following along with my exact project, you fill find all the images on Github.

So, right-click on the wwwroot folder, select Add, then New Folder. Rename the folder images. Then copy the image to that folder.

And now we’re ready to add all the elements we need in the Razor section of the component. Here’s the code:

<div>
    <img src="/images/Forest Monsters.png" />
    <div>
        <h5>Forest Monsters</h5>
        <div>
            Technologies:
            <div>C#</div>
            <div>Unity</div>
        </div>
        <p>A 2D game made with Unity with C# scripting. Your task is to save the enchanted forest.</p>
        <div>
            Links:
            <div>Github</div>
            <div>YouTube</div>
            <div>My Prospero Coder blog</div>
            <div>download</div>
        </div>
        <p>Click to view more...</p>
    </div>
</div>

@code {

}

As you can see, this is just HTML, with nothing Razor-specific at this stage. The code is extremely basic, it has no styling at all and it’s all hard-coded. We’ll be fixing all these issues as we proceed, but you have at least something you can see. Speaking of which, this is not an independent component, so it must be embedded in another component. Go to the Index.razor page that we were working on before, remove the two counters and the text above and add the Project component instead. The code in the Index.razor file should look like so:

@page "/"

<PageTitle>Index</PageTitle>

<h1>My Projects</h1>

<Project />

Now run the app and you will see our Project component displayed:

It’s pretty ugly, but it will do for now. In the next part of the series we’ll see how to style it and add the icons. And now let’s move on to the next component.

The ProjectDetails Component

Whenever a user clicks on a project, they will be taken to the details page for that component. The page will include more information about the project plus some working links. The ProjectDetails component is going to be a navigable component, so let’s create it in the Pages folder. Right-click on the Pages folder, add a new Razor Component… like you did before and name it ProjectDetails. When it opens in the editor, we’ll add a @page directive so that we can navigate to this page. Let’s also display the image and all the information we need about the project. The code should look like this:

@page "/ProjectDetails"

<div>
    <img src="/images/Forest Monsters.png" />
    <div>
        <h5>Forest Monsters</h5>
        <p>A 2D game made with Unity with C# scripting. Your task is to save the enchanted forest.</p>
        <div>
            Technologies used in this project:
            <div>C#</div>
            <div>Unity</div>
        </div>        
        <div>
            Useful links related to this project:
            <div>Github</div>
            <div>YouTube</div>
            <div>My Prospero Coder blog</div>
            <div>download</div>
        </div>
    </div>
</div>

@code {

}

Well, the code looks almost the same as in the Project component for now. To view the component we have to manually enter its URI in the address bar. We’ll fix this later when we implement navigation. So, run the app and enter the URI like so:

Now you can see the details page for the project:

Fortunately, some basic navigation has been already implemented for you when the project was created. If you click Home in the sidebar, you will navigate to the home page, which is the Index.razor page.

Anyway, we can now display a single project, be it its summary or details (which do not differ that much now). What if we wanted to display multiple projects side by side?

The Components Displaying Multiple Projects

There are going to be three components in our project that will display multiple projects. These are going to be ProjectDisplay, ProjectsByCategory and ProjectsByTech.

ProjectsByCategory and ProjectsByTech should be independent components. ProjectsDisplay, on the other hand, should be a dependent component. It will be embedded inside the two pages as well as in the home page.

Let’s start with the ProjectsDisplay component. Create a new Razor component in the Shared folder and name it ProjectsDisplay. As we only have one hard-coded Project component, we’ll use it multiple times, just to see what the ProjectsDisplay component looks like. Here’s the (temporary, of course) code:

<Project />
<Project />
<Project />
<Project />
<Project />

@code {

}

And now let’s modify the Index component (defined in the Index.razor file) to display this component instead of a single project. The code should look like this:

@page "/"

<PageTitle>Index</PageTitle>

<h1>My Projects</h1>

<ProjectsDisplay />

If you now run the app, you will see the five projects displayed:

You have to scroll to see them all.

The code above is a good example of component nesting in Blazor. Project is nested inside ProjectsDisplay and the latter is nested inside the Index component.

The ProjectsByCategory and ProjectsByTech components will display multiple projects as well. They will display projects filtered by category or by technology using the ProjectsDisplay component. As we haven’t implemented the filtering functionality yet, let’s just make them display three projects each for now.

Create the two pages in the Pages folder. They should both contain almost identical code for now. Only the URIs and the headers should be different. Here’s the ProjectsByCategory page:

@page "/ProjectsByCategory"

<h3>Projects By Category</h3>

<Project />
<Project />
<Project />

@code {

}

And here’s the ProjectsByTech page:

@page "/ProjectsByTech"

<h3>Projects By Tech</h3>

<Project />
<Project />
<Project />

@code {

}

Now run the app and type in “ProjectsByCategory” in the address bar. This will take you to the appropriate page:

Then change the address to “ProjectsByTech” and you will be taken to the other page.

The Sidebar Components

Finally, we’re going to create three components that will sit in the sidebar, CategoriesMenu, TechsMenu and SocialMenu. They’re all going to be dependent components, so we’ll put them in the Shared folder.

So, create the three components in the Shared folder. Let’s have a look at CategoriesMenu first. As with the other components before, we’ll hard-code everything for now. Here’s the code:

<h3>Categories</h3>

<p>Web Projects</p>
<p>Games</p>
<p>Books</p>

@code {

}

Now let’s do the same with the TechsMenu component:

<h3>Technologies</h3>

<p>C#</p>
<p>Blazor</p>
<p>.NET MAUI</p>

@code {

}

The SocialMenu component should contain links to my blogs and YouTube channels, as well as contact information. This is going to be fixed content, so we can hard-code it now and it will remain hard-coded. We’ll need some images for the links. I run two blogs (Prospero Coder with programming and 3D modeling-related stuff and Prospero English – with stuff related to the English language). I also run three YouTube channels: Prospero Coder, Prospero Blender and Prospero English. For the links to these resources we’ll need the following images:

For the blogs:

Logo Coder.png

Logo English.png

For the YouTube channels:

Prospero Coder YT Banner.png

Prospero Blender YT Banner.png

Prospero English YT Banner.png

To keep things organized, let’s create a subfolder in the images folder inside the wwwroot folder and name it SocialMedia. Then all you have to do is copy all the images and paste them there:

Now we can put the links in the SocialMenu component. We’ll use the regular HTML anchor tags for the links. We’ll set the target attribute to _blank to ensure the link opens in a new tab. We’ll also add some contact text below. Don’t worry about the styling for now.

As we know that no logic will be required for this component, you can remove the code section completely. Here’s the code:

<div>
    <div>
        <h6>My Blogs</h6>

        <div>
            <a href="https://prosperocoder.com/" target="_blank">
                <img src="images/SocialMedia/Logo Coder.png">
            </a>
            <a href="https://prosperoenglish.com/" target="_blank">
                <img src="images/SocialMedia/Logo English.png">
            </a>
        </div>
    </div>

    <div>
        <h6>My YouTube Channels</h6>

        <div>
            <a href="https://www.youtube.com/c/ProsperoCoder/" target="_blank">
                <img src="images/SocialMedia/Prospero Coder YT Banner.png">
            </a>
            <a href="https://www.youtube.com/c/ProsperoBlender" target="_blank">
                <img src="images/SocialMedia/Prospero Blender YT Banner.png">
            </a>
            <a href="https://www.youtube.com/c/ProsperoEnglish" target="_blank">
                <img src="images/SocialMedia/Prospero English YT Banner.png">
            </a>
        </div>
    </div>


    <div>
        <h6>Contact</h6>
        <div>
            prosperocoder@gmail.com
        </div>
    </div>
</div>

Now, with the three components implemented, we must embed them in the sidebar. The right place to do it is inside the NavMenu component that was created for you when you created the Blazor project. You will find it inside the Shared folder.

If you open the NavMenu.razor file, you will see the links to the home page, to the Counter page and to the FetchData page:

<div class="top-row ps-3 navbar navbar-dark">
    ...
</div>

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

@code {
    ...
}

We don’t actually need the links except for the Home page, so let’s delete them. They’re not part of our project.  Then, below the Home page link let’s add our three components:

...
<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
    <nav class="flex-column">
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </div>
        <CategoriesMenu />
        <TechsMenu />
        <SocialMenu />
    </nav>
</div>

@code {
    ...
}

Let’s run the app. This is what our new components look like at this moment:

Really nice, right? Well… The text is hardly visible, the images are way too big and part of the content must be scrolled into. I admit, it sucks. But all the components are there and we’ll take care of them in the next part of the series where we will be talking about styling. I hereby promise you that after you finish the next part, your components will look much better.

Conclusion

In this part of the series we learned how to create a Razor component and what its main three sections are. We talked about different types of components. We know components can be nested inside other components. We also know how to make use of Hot Reload to view our changes in Razor code live. Finally, we implemented the first and very basic versions of the components that we’ll be using in the My Portfolio project. And now let’s add styling to our app so that it looks at least decent.


Spread the love

Leave a Reply