Working With Layout Page In Blazor

Some part of page remains as is throughout the application such as header, navigation, footer etc. ASP.net application introduced MasterPage and ASP.net MVC introduced layout page that contains common UI parts, so we need not to write duplicate code in every page. Blazor also has Layouts that resolved duplicate code problem.

Introduction
 
Some part of the page remains as is throughout the application such as header, navigation, footer etc. ASP.NET application introduced MasterPage and ASP.net MVC introduced layout page that contains common UI parts, so we don't need to write duplicate code in every page. Blazor also has Layouts that resolved the duplicate code problem.
 
Basically, every part of the application in Blazor is a component, so Layout is also considered as a component in Blazor applications. The component may contain Razor syntax, C# code, data binding etc. The layout implements Microsoft.AspNetCore.Blazor.Layouts.ILayoutComponent interface. This interface adds "Body" Property to the Layout so the content of the page is rendered inside the layout. It is very similar to Razor Layout view except for server side property implementation.

The default template of Blazor contains MainLayout.cshtml under the shared folder. It works as Layout page.
 
Example
  1. @implements ILayoutComponent  
  2.   
  3. <div class="container-fluid">  
  4.     <div class="row">  
  5.         <div class="col-sm-3">  
  6.             <NavMenu />  
  7.         </div>  
  8.         <div class="col-sm-9">  
  9.             @Body  
  10.         </div>  
  11.     </div>  
  12. </div>  
  13.   
  14. @functions {  
  15.     public RenderFragment Body { getset; }  
  16. }  
There are mainly two ways to render component with Layouts
  1. Using @layout directive or Layout attribute
  2. Define layout globally 
Using @layout directive or Layout Attribute
 
We can define the layout for Blazor component by using @layout directive. At the time of compilation, @layout directive converted into Layout attribute which applied to the Blazor component class. Either way, if our component is class based, we can use Layout attribute directly in class.
 
Example

Using @Layout directive

  1. @layout MainLayout  
  2. @page "/usingdirective"  
  3.   
  4. <h2>@Title</h2>  
  5.   
  6. @functions {  
  7.     string Title = "Layout page defined using @layout directive";  
  8. }  
Using Layout attribute
  1. using BlazorDemoApp.Shared;  
  2. using Microsoft.AspNetCore.Blazor.Components;  
  3. using Microsoft.AspNetCore.Blazor.Layouts;  
  4. using Microsoft.AspNetCore.Blazor.RenderTree;  
  5.   
  6. namespace BlazorDemoApp.Pages  
  7. {  
  8.     [Route("/usingattribute")]  
  9.     [Layout(typeof(MainLayout))]  
  10.     public class LayoutdefinedUsingattribute : BlazorComponent  
  11.     {  
  12.         public string Title { getset; } = "Layout page defined using layout Attribute";  
  13.         protected override void BuildRenderTree(RenderTreeBuilder builder)  
  14.         {  
  15.             builder.OpenElement(1, "h2");  
  16.             builder.AddContent(2, Title);  
  17.             builder.CloseElement();  
  18.         }  
  19.     }  
  20. }  
Define layout globally
 
The _ViewImports.cshtml file was introduced in ASP.net MVC and it provides a mechanism to make directives available to Razor pages globally so that we aren't required to add them to pages individually. We can also use this file to define Layout page in Blazor. If we define Layout page in this file, Layout is automatically applied to all the Blazor pages in the folder heirarchy.
 
_ViewImports.cshtml 
  1. @layout MainLayout  
Note that, we can also define the namespaces that are used in all the views in a folder to _viewImports.cshtml file. 

Nested layouts
 
Blazor component also supports the nested layouts; i.e., Blazor component can reference a layout which references another layout.
 
Example
 
In the following example, I have created a nested layout. The Master layout page contains a header (MainLayout.cshtml) and the other layout has the header and it refers to the MasterLayout component as a Layout.
 
 
 
MainLayout.cshtml
  1. @implements ILayoutComponent  
  2.   
  3. <div class="container-fluid">  
  4.     <div class="row">  
  5.         <div class="col-sm-3">  
  6.             <NavMenu />  
  7.         </div>  
  8.         <div class="col-sm-9">  
  9.             @Body  
  10.         </div>  
  11.     </div>  
  12. </div>  
  13.   
  14. @functions {  
  15.     public RenderFragment Body { getset; }  
  16. }  
OtherLayout.cshtml
  1. @layout MainLayout  
  2. @implements ILayoutComponent  
  3.   
  4. <div class="container-fluid">  
  5.     <div class="row">  
  6.         <div class="col-sm-12">  
  7.             <h2>Nested Layout Example</h2>  
  8.         </div>  
  9.     </div>  
  10.     <div class="row">  
  11.         <div class="col-sm-12">  
  12.             @Body  
  13.         </div>  
  14.     </div>  
  15. </div>  
  16.   
  17. @functions {  
  18.     public RenderFragment Body { getset; }  
  19. }  
nestestedLayout.cshtml
  1. @layout OtherLayout  
  2. @page "/nestedlayout"  
  3.   
  4. <h3>@Title</h3>  
  5.   
  6. @functions {  
  7.     string Title = "This is child page";  
  8. }  
Summary
 
Layout page helps us to reduce duplicate code in our application and helps us to make the look and feel consistent throughout the application. It is very similar to Layout in ASP.net MVC application. Blazor also supports nested layout.

You can view or download the source code from the GitHub link here.