Layouts in Blazor

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
Last updated: 12/10/2024 2:39:03 PM

Latest Updates

© 2023 - 2024 - Mike Brind.
All rights reserved.
Contact me at Mike dot Brind at Outlook.com