Blazor Bites - Layouts

Blazor Bites Series


Post valid for: Blazor 0.4.0
Please remember that Blazor is an experimental project and is going to be changing regularly. IT IS NOT PRODUCTION READY.


Layouts

When developing an application you typically want it to maintain a consistent look and feel. Back in ye old days of web development we had static HTML files and common elements, such as headers and footers, would have to be copied between files. And a change to the layout would mean updating every file in the site. As time moved on we had includes with Classic ASP, master pages with WebForms and Razor has the concept of Layouts. All these things made defining and maintaining site wide look and feel much easier.

So how does Blazor handle layouts?

I'm glad you asked - Layout components.

Layout components are very similar to a normal Blazor component except for one difference. They inherit from BlazorLayoutComponent. This class has a single property, Body. This property must be specified in the Razor markup of the component as this where the content of the layout will be rendered.

Example
@inherits BlazorLayoutComponent

<SiteHeader />

<div class='container-fluid'>
    <div class='row'>
        <div class='col-sm-12 padding-top-15'>
            @Body
        </div>
    </div>
</div>

The example above is a simple layout component. I have also referenced another component, SiteHeader, inside the layout just to show that that is possible as well. In fact you can do anything with a layout component you can do with a regular one, such as inject services or use data binding. They can even be defined in pure C# if you like.

Loading a component into a layout

In order to load a component into a certain layout you must define which layout it is to use. This is done using the @layout directive. Then when the component is requested its content is loaded into the layout component at the point the @Body tag is defined.

If you are writing a component in pure C# and you wish to have it use a layout component. Then you can decorate it with the [LayoutAttribute], as this is what the compiler will convert the @layout directive to anyway.

Example
// Using .cshtml

@layout MainLayout
@page "/"

<h1>Overview</h1>

...
Example
// Using pure C#

[Layout(typeof(MainLayout))]
public class Overview : BlazorComponent
{
    ...
}

Nesting layouts

At times you may want to nest layouts. You may wish to have a slightly different layout between certain areas of your site for example, while keeping a consistent header and footer. This is all supported with Blazor layout components.

Example
// ExpensesComponent

@layout AccountLayout
@page "/account/expenses"

<h1>Expenses</h1>

...
// AccountLayout

@layout MainLayout
@inherits BlazorLayoutComponent

<nav>
    <NavLink href="/account/incomes">
        Income
    </NavLink>
    <NavLink href="/account/expenses">
        Expenses
    </NavLink>
</nav>

<section>
    @Body
</section>
// MainLayout

@implements ILayoutComponent

<SiteHeader />

<div class='container-fluid'>
    <div class='row'>
        <div class='col-sm-12 padding-top-15'>
            @Body
        </div>
    </div>
</div>

In the code examples above the final output would be the ExpensesComponent being rendered in the AccountLayouts @Body tag. Which would then be rendered in the MainLayouts @Body tag.