Blazor Server Project #5: Creating and Using Page Layout
Applying a layout to an individual page, all pages in an app, and all components in a folder and subfolders
This article is the fifth in a series covering the Blazor Server Project: (1) How to create a CRUD operation using Dapper (2) Building a dropdown list involves a 1:N relationship (3) How to implement a checkbox list involving an M:N relationships (4) Understanding URL routing and navigation (5) Creating and using page layout (6) How to create a reusable modal dialog component (7) Practical guide to making a master-detail page (8) Master-detail page using dynamic query (9) How to avoid SQL injection attacks (10) Hiding/showing HTML elements (11) Migrate to ASP.NET Core 6.0 (12) Installing ASP.NET Core Identity (13) Integrating Identity tables into the existing project database (14) Authentication and authorization (15) Role-based authorization (16) How to implement Google Authentication (17) Facebook Authentication and Authorization (18) How to configure Twitter Authentication (19) How to Customize Password Policy (20) Account Lockout Policy
These articles are for anyone who wants to learn how to build Blazor Server applications in a practical approach through some sample projects. It will be straightforward if you have some experience with C#, HTML, CSS, and SQL.
Blazor Server and Blazor WebAssembly support page layout. The layout has been highlighted at a glance in the previous article, Blazor Server Project #4, that discussed routes.
A layout is a template with one or more elements placeholders such as a header, footer, copyright, menu, etc. Every page may use the same layout and or a different layout. Like on the page components, you can do a layout component like dependency injection, data binding, and nesting other components. The difference is the layout has to inherit from the LayoutComponentBase class.
There are three ways to apply a layout to pages. (1) Specifying a layout explicitly for an individual page. (2) Specifying a default layout for all pages in an app. (3) Specifying the layout for all components in a folder and subfolders.
All of the following reviews base on the application built in the previous article, Blazor Server Project #3. Please download the source code via the link below.
Specifying a layout explicitly for an individual page
As an example, we will create a simple layout and apply it to a page.
Create a simple layout
- Open BookApp using Visual Studio 2019.
- In the
Solution Explorerpanel on the right side of the screen, selectPages|Add|Razor Component... - Type
SimpleLayout.razoras the file name, clickAdd. - Please copy the following code, paste it to the
SimpleLayout.razorpanel on the left side of the screen.
Listing 1 BookApp\Shared\SimpleLayout.razor
@inherits LayoutComponentBase
@BodyThe SimpleLayout.razor above has only one element using the Razor syntax @Body to specify the layout markup's location where the content is rendered.
Apply a layout explicitly to a page
Every page may select which layout to use by stating the name of the layout with the @layout directive. For example, add the @layout SimpleLayout directive to the Index.razor page.
Listing 2 BookApp\Pages\Index.razor
@layout SimpleLayout
@page "/"<h1>Hello, world!</h1>Welcome to your new app.At run time, it displays the following homepage.

Specifying a default layout for all pages in an app
MainLayout component
When you create a Blazor app using one of the Blazor project templates, the MainLayout.razor component is automatically installed into the Shared folder.
Listing 3 BookApp\Shared\MainLayout.razor
@inherits LayoutComponentBase<div class="sidebar">
<NavMenu />
</div><div class="main">
<div class="top-row px-4">
<a href="https://docs.microsoft.com/aspnet/"
target="_blank">About</a>
</div>
<div class="content px-4">
@Body
</div>
</div>The Router component in the App.razor file sets the default layout to the MainLayout component.
Listing 4 BookApp\App.razor
<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>Each page that is not specified to any layout will apply the default layout. We will apply it to Index.razor as an example.
- Open the
Index.razorfile. The@layout SimpleLayoutdirective shows theIndex.razorstill referencesSimpleLayout.razor. - Delete the first line code —
@layout SimpleLayoutdirective — automatically theIndex.razorreferences default layout (MainLayout.razor). - At run time, the
Index.razorcomponent applies the default layout and displays the following homepage.

- Delete the
SimpleLayout.razorfile because the project doesn't need it anymore.
Specifying the layout for all components in a folder and subfolders
You can create a template file named _Imports.razor in a folder if all components in the folder and recursively in all of its subfolders use the same layout. For example, all components in a folder named Superuser and recursively in all of its subfolders use the same layout named SpecialLayout.razor.
- Create a file named
_Imports.razorin theSuperuserfolder. - Add the
@layout SpecialLayoutdirective into the file.
There’s no need to add @layout SpecialLayout repeatedly to all of the .razor files within the folder and subfolders, and so do @using directives.
Modifying MainLayout.razor
We needn’t About element, so we replace it with the current day and date. Below is the modified MainLayout.razor.
Listing 5 BookApp\Shared\MainLayout.razor
@inherits LayoutComponentBase<div class="sidebar">
<NavMenu />
</div><div class="main">
<div class="top-row px-4">
<a>@today.ToString("dddd, dd MMMM yyyy")</a>
</div><div class="content px-4">
@Body
</div>
</div>@code {
DateTime today = DateTime.Today;
}Nested Layouts
Layout components can also be nested. A page component can reference a layout, which in turn references another layout. For example, the Index.razor component references a layout named GreetingLayout.razor which references MainLayout.razor. The GreetingLayout.razor layout displays greetings at the top of the page content, inside the MainLayout.razor layout. The following are the steps.
- Create a layout file named
GreetingLayout.razorin theSharedfolder. - Please copy the following code, then paste it into the
GreetingLayout.razorfile.
Listing 6 BookApp\Shared\GreetingLayout..razor
@layout MainLayout @* references MainLayout.razor *@
@inherits LayoutComponentBase<h5>Good @time!</h5>
<br />@Body@code {
private string time;
protected override void OnInitialized()
{
int hour = DateTime.Now.Hour;
if (hour < 5 && hour > 17)
time = "Evening";
else if (hour < 12)
time = "Morning";
else
time = "Afternoon";
}
}- Add the following code into the
Index.razorfile so that the contents are as follows.
Listing 7 BookApp\Shared\GreetingLayout..razor
@page "/"
@layout GreetingLayout @* references GreetingLayout.razor *@<h1>Hello, world!</h1>Welcome to your new app.- At run time, the
Index.razorcomponent applies the nested layout and displays the following homepage.

A layout — like another component — can use data binding, dependency injection, and nesting other components. The two layouts above, the modified MainLayout.razor and GreetingLayout.razor.razor, use one-way data binding.
