Skip to content

Commit

Permalink
Blazor layout sections (#28660)
Browse files Browse the repository at this point in the history
  • Loading branch information
guardrex authored Apr 26, 2023
1 parent 2ff47b4 commit 3497619
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
8 changes: 8 additions & 0 deletions aspnetcore/blazor/components/layouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,14 @@ The following rendered HTML markup is produced by the preceding nested layout. E

When routable components are integrated into a Razor Pages app, the app's shared layout can be used with the components. For more information, see <xref:blazor/components/prerendering-and-integration>.

:::moniker range=">= aspnetcore-8.0"

## Sections

To control the content in a layout from a child Razor component, see <xref:blazor/components/sections>.

:::moniker-end

## Additional resources

* <xref:mvc/views/layout>
Expand Down
80 changes: 80 additions & 0 deletions aspnetcore/blazor/components/sections.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: ASP.NET Core Blazor sections
author: guardrex
description: Learn how to to control the content in a Razor component from a child Razor component.
monikerRange: '>= aspnetcore-8.0'
ms.author: riande
ms.custom: mvc
ms.date: 04/18/2023
uid: blazor/components/sections
---
# ASP.NET Core Blazor sections

To control the content in a Razor component from a child Razor component, Blazor supports *sections* using the following built-in components:

* `SectionOutlet`: Renders content provided by `SectionContent` components with matching `SectionName` or `SectionId` arguments. Two or more `SectionOutlet` components can't have the the same `SectionName` or `SectionId`.

* `SectionContent`: Provides content as a <xref:Microsoft.AspNetCore.Components.RenderFragment> to `SectionOutlet` components with a matching `SectionName` or `SectionId`. If several `SectionContent` components have the same `SectionName` or `SectionId`, the matching `SectionOutlet` component renders the content of the last rendered `SectionContent`.

Sections can be used in both [layouts](xref:blazor/components/layouts) and across nested parent-child components.

Although the argument passed to `SectionName` can use any type of casing, the documentation adopts kebab casing (for example, `top-bar`), which is a common casing choice for HTML element IDs. `SectionId` receives a static `object` field, and we always recommend Pascal casing for C# field names (for example, `TopbarSection`).

In the following example, the app's main layout component implements an increment counter button for the app's `Counter` component.

Add the namespace for sections to the `_Imports.razor` file:

```razor
@using Microsoft.AspNetCore.Components.Sections
```

In the `MainLayout` component (`Shared/MainLayout.razor`), place a `SectionOutlet` component and pass a string to the `SectionName` parameter to indicate the section's name. The following example uses the section name `top-bar`:

```razor
<SectionOutlet SectionName="top-bar" />
```

In the `Counter` component (`Pages/Counter.razor`), create a `SectionContent` component and pass the matching string (`top-bar`) to its `SectionName` parameter:

```razor
<SectionContent SectionName="top-bar">
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SectionContent>
```

When the `Counter` component is accessed at `/counter`, the `MainLayout` component renders the increment count button from the `Counter` component where the `SectionOutlet` component is placed. When any other component is accessed, the increment count button isn't rendered.

Instead of using a named section, you can pass a static `object` with the `SectionId` parameter to identify the section. The following example also implements an increment counter button for the app's `Counter` component in the app's main layout.

If you don't want other `SectionContent` components to accidentally match the name of a `SectionOutlet`, pass an object `SectionId` parameter to identify the section. This can be useful when designing a [Razor class library (RCL)](xref:blazor/components/class-libraries). When a `SectionOutlet` in the RCL uses an object reference with `SectionId` and the consumer places a `SectionContent` component with a matching `SectionId` object, an accidental match by name isn't possible when consumers of the RCL implement other `SectionContent` components.

The following example also implements an increment counter button for the app's `Counter` component in the app's main layout, using an object reference instead of a section name.

Add a `TopbarSection` static `object` to the `MainLayout` component in an `@code` block:

```razor
@code {
internal static object TopbarSection = new();
}
```

In the `MainLayout` component's Razor markup, place a `SectionOutlet` component and pass `TopbarSection` to the `SectionId` parameter to indicate the section:

```razor
<SectionOutlet SectionId="TopbarSection" />
```

Add a `SectionContent` component to the app's `Counter` component that renders an increment count button. Use the `MainLayout` component's `TopbarSection` section static `object` as the `SectionId` (`MainLayout.TopbarSection`).

In `Pages/Counter.razor`:

```razor
<SectionContent SectionId="MainLayout.TopbarSection">
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SectionContent>
```

When the `Counter` component is accessed, the `MainLayout` component renders the increment count button where the `SectionOutlet` component is placed.

> [!NOTE]
> `SectionOutlet` and `SectionContent` components can only set either `SectionId` or `SectionName`, not both.
2 changes: 2 additions & 0 deletions aspnetcore/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ items:
uid: blazor/components/index
- name: Layouts
uid: blazor/components/layouts
- name: Sections
uid: blazor/components/sections
- name: Control <head> content
uid: blazor/components/control-head-content
- name: Cascading values and parameters
Expand Down

0 comments on commit 3497619

Please sign in to comment.