A layout is a particular type of Razor component. Its role is to provide a common look and feel to all pages that it is assigned to. The layout will usually include the HTML for the basic structure of all pages that it is intended to affect.
The layout must inherit LayoutComponentBase
and render its Body
property, by including @Body
where the content of page components should appear. The layout in the default template is MainLayout.razor in the Pages/Shared folder:
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
The NavMenu component and the link to the official documentation site is included in the layout, ensuring that they appear in the same position in all pages that use the layout. Page content always appears where @Body
is placed.
Layouts in other ASP.NET Core framework (MVC and Razor Pages) include all common aspects of the page, including the head element, links to style sheets, site-wide script files, the footer and so on. This is not necessary in a Blazor application as these elements can be specified in the single page that hosts the application (index.html in the wwwroot folder).
Assigning Layouts
Layouts can be assigned to content pages via the layout
attribute:
@page "/"
@layout = MainLayout;
<h1>Home</h1>
Alternatively, they can be assigned to multiple pages in an _Imports.razor file, which affects all content pages in the same folder as the _Imports.razor file and all subfolders. Layouts specified in the individual content page override the layout specified in the _Imports.razor file.
The default layout for an entire application can be set via the DefaultLayout
property of the RouteView
component. An example of its use can be found in the App.razor file belonging to the standard project template:
<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>
Layouts set in _Imports.razor files will override any value set here.
Nesting Layouts
Layouts can be nested, that is, it is perfectly legal to specify the layout for a layout. You might want to take advantage of this capability if a subset of pages share common features not shared by other pages.
The rules that apply to child layouts is the same as the top level one: they must inherit from LayoutComponentBase
and include @Body
. Here is a child layout named NestedLayout.razor which includes another component, NestedComponent as part of its markup:
@layout MainLayout
@inherits LayoutComponentBase
<NestedComponent />
@Body
The child layout specifies MainLayout as its layout. Pages that should include the NestedComponent as part of their output will specify NestedLayout
as their layout:
@page "/somepage"
@layout NestedLayout
.. content