Understanding routing and pages
With any app you use, whether it’s a native mobile or Windows app or a website, you will see it is made up of a set of pages users can move between. In the scope of the web specifically, we have traditional websites and web apps that work on the server, and we have apps that run fully in the browser, such as Blazor WebAssembly apps.
With the traditional web approach, there is no actual navigation happening in the browser because what happens is that the browser sends a request to the server for a specific URL, the server comes back with the HTML, and then the browser just renders it. On the other hand, with single-page applications, the whole app is running totally in the client, and we have a single HTML page that holds the entire UI of our app. Frameworks such as Blazor, Angular, or ReactJS, for instance, are responsible for replacing part of the UI according to the redirected link with the corresponding component, and that is what we call routing.
Routing is the process of matching the body component of the app with the requested URL. As seen in the Building layouts in Blazor section in Chapter 3, Developing Advanced Components in Blazor, within the layout component, we render the @Body
property and that’s where the page content of a specific URL will be shown. Now, we understand components and routing, but what are pages in Blazor?
Basically, a page in Blazor is a normal Razor component but we declare a router for it at the very top using the @page
razor directive. This router is the URL used to access the component as follows:
@page "/counter"...
The /counter
value defined in the previous code snippet is used to declare that the Counter
component can be accessed using the URL (app_base_url/counter
).
Now, let’s see who is responsible for this routing experience in Blazor.
The Router component in Blazor
If you navigate to the App.razor
component, which is the root of every Blazor app, you will see that the first component called Router
wraps all other components and it has a parameter called AppAssembly
, which we will talk about in a bit:
<Router AppAssembly="@typeof(App).Assembly"> ... </Router>
The Router
component is responsible for reading the routes and matching them with the components when the user navigates to that route or link.
The AppAssembly
parameter, which is set to the Assembly
of the project, tells the Router
component where to look for components that have routes. By default, the Router
component will look into the project assembly only, but if you have other pages existing in another Razor Class library project, Router
won’t be able to recognize these routes. To make Router
look for pages in many assemblies, we need to use other parameters called AdditionalAssemblies
and pass a collection of assemblies so that Router
will look for and register all the available routes.
The following code snippet shows an example of adding the Razor Class Library assembly to Router
to crawl its pages:
@using BooksStore.Blazor.Components<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="new[] { typeof(Component1).Assembly }"> ...
Component1
represents a component existing in a Razor Class Library project. We just use it to bring the full assembly that contains a certain type. In our BooksStore
project, all our pages will be defined in the BooksStore
Blazor WebAssembly; the Razor Class Library project will not contain pages, just shared components.
Creating your first page
After learning about Router
and how navigation works, let’s get started by creating our first page and discover the NavigationManager
class, which helps us write code to navigate, as well as using the PageTitle
component introduced in Blazor with .NET 6, which allows us to change the title of the page in the browser tab:
- Create a new component in the
Pages/UserPages
folder and name itAbout.razor
. This component will be a simple page that represents some info about the project. - At the very top of the
About.razor
file, we need to declare a route for this component to be accessible through{App_Url}/about
using the@
page
directive. - In addition to that, when the user navigates to the
About
page, we need to change the title in the browser tab, and we can achieve that using thePageTitle
component as follows:@page "/about"<PageTitle>About</PageTitle>...
- Finally, add some UI content to fill out some information about the app:
...<h2>Welcome to BooksStore</h2><p>BooksStore allows you to disover best titles in tech and more</p>
If we run the app and navigate to /about
, we should see the following page:
Figure 4.1 – The About page
Note
Each page can have multiple routes, for example, the Index page can have /
, /index
, and /home
. Therefore, Router
will register three URLs for the same component.
The examples you have seen in this section show you just the basics of navigation and routing in a simple setup. In real-world apps, some pages are connected, and we need to send data between those pages using parameters.