Creating a top menu search bar in Blazor

Blazor is a single-page application (SPA) framework, based on Razor and HTML. While it is still in the experimental phase, it offers an easy way for .NET developers to build front-end web applications.

In this article, I will go over the process of creating a search bar in the main layout of an application, that allows the user to filter through a ‘feed’. If you don’t have any previous knowledge of Blazor, you can check out the official docs to see how to install it and build your first application.

What we want to end up with at the end of the article is a search input that loads the main part of the application in real-time:

Setting up the data

To simplify the tutorial, we will use a JSON file to dynamically load the data, instead of getting it from a web service. To do this, create a new file in the sample-data folder from wwwroot:

And add the following content to it:

Creating the search functionality

We will start things off by creating the search input and handling the events. In the MainLayout.cshtml file, change the About link to an input, like this:

So the top bar of the page looks like this:

As you can see by looking at the element we added, there are two things we need to create:

  • the SearchTerm property that the search input is bound to (you can read more about data binding here);
  • the SearchKeyDown method that is called based on the onkeydown event (in this tutorial, I will trigger the search based on the user hitting the ENTER key; you can choose to have a search button as an alternative).

Apart from these two, we will also inject a UriHelper instance into the MainLayout, so we can navigate to the search page.

The SearchKeyDown method will check if the pressed key is “Enter” and, if that is the case, navigate to the /search/{SearchTerm} URI. It will also notify the application that the page’s state has changed and that it needs to be re-rendered. The need to do this might be eliminated in future Blazor versions, but it currently needs to be done manually; otherwise, Blazor will not be aware that the page has changed from Index to Search, and it will look for the Search page properties in the wrong place.

This is the final version of the MainLayout:

Setting up the Feed and Posts

The Feed component is the one that will handle the way posts are displayed. Since this is going to be used both on the index page and on the search page, it makes sense to have it ready.

In the Shared folder, create a new folder called Components. Here, create a new Razor View called Post. To keep things simple, a post will only have 2 fields: a title and its children (anything that is between <Post> and </Post>). This is what the file looks like:

For this tutorial, I will handle multiple things in the Feed component: getting the posts from the JSON file that we created, deciding which of them to display (either all of them or only those meeting the filter criteria), and actually displaying them. Depending on your project’s design, you might want to delegate the data fetching and decision making to some other component, and pass the posts to the Feed as a children. It’s up to you.

First of all, create another Razor View called Feed in the Components folder. To start with the data fetching, first create a new class, FeedElement, in the functions body of the component. This is essentially a post, and it contains a title and some content. We’ll have a list of FeedElement objects to store the JSON data, and a GetData method:

Next up, we need to decide which of the posts to show. For this, we will use a Filter field to store the user-passed value.

There are 2 situations when we need to make this decision. The first one is, obviously, when the component is loaded. For the second one, we need to think about the search functionality: the user could input a new value while on the Search page, so the Feed component will be the same, but the Filter value will change. So we will load the data both in the OnInitAsync method and in OnParametersSet, by delegating that responsibility to a separate method, Load.

For displaying the posts, we will loop through the list of FeedElement objects and display a Post component for each of them. This is the finalized Feed component:

The OnParametersSet method also needs to notify the application that its state has changed, in order to re-render the component. This might change in future Blazor versions, but it is necessary for now.

The way posts are filtered (in the Load method) is by converting everything to lowercase – so if the user searches for “tomatoes”, results for “Tomatoes” also show up, and looking for the search term in both the title of the posts and the content.

Setting up the Index and Search pages

The application is almost done. All we need now is a way to display the feed posts. On the index page, we will simply display all the posts that we read, with no filter. So the Index.cshtml file only contains a closed Feed tag:

As for the Search page, create a new RazorView in the Pages folder. Based on our design from the MainLayout, this needs to take a parameter in the URI, so we will need to store the search term. Apart from that, we only need to display a Feed component and pass the search term as the Filter attribute. For the same reason as in the Feed, we need to let know that the state of the application has changed when the user searches for a new term:


This is what the search page should look like now:

Searching for different terms should reload the components accordingly. If anything, I suggest experimenting with the different events (OnInit, OnParametersSet) to understand how they work and what happens if you don’t notify the state change.

If you have any questions, feel free to comment below or check the Blazor docs. The full code can be found on GitHub, and any possible changes to the code base will be updated there.

About Mircea Oprea

Mircea Oprea is a software developer based in Denmark, interested in API design, graphics programming, and Agile methodologies. He enjoys discovering and exploring new technologies, a passion that resulted in projects and articles that can be found on

View all posts by Mircea Oprea →