| MAUI-Headless-Pattern :👈 | 👉:MAUI Introduction |
.NET MAUI ShellContent vs Pages |
.NET MAUI ShellContent vs Pages
In .NET MAUI Shell, ShellContent and Pages (ContentPage, TabbedPage, etc.) serve different purposes and exist at different levels of the navigation hierarchy. Although both are related to navigation,only a Page represents the actual screen displayed to the user.
Many developers initially confuse them because both ultimately display UI, but they play very different roles.
High-Level Difference
Think of Shell as a navigation framework
- ShellContent = Navigation container that tells Shell which page belongs to a route/menu/tab
- ContentPage (or other Page) = Actual UI screen displayed to the user.
- Shell = Root navigation framework. (Root navigation structure)
- FlyoutItem / TabBar / Tab = Visual navigation groups.
- ShellContent connects a Page to Shell navigation.
Simple analogy:
- Shell = Entire Hotel
- FlyoutItem/Tab = Floors
- ShellContent = Room Number
- Page = Actual Room
The guest stays in the room (Page), not the room number (ShellContent)
Shell Navigation Hierarchy
Shell
├── FlyoutItem
│ ├── Tab
│ │ └── ShellContent
│ │ └── HomePage
│ └── Tab
│ └── ShellContent
│ └── SettingsPage
Example
<Shell>
<FlyoutItem Title="Home">
<Tab>
<ShellContent
Title="Dashboard"
ContentTemplate="{DataTemplate local:HomePage}" />
</Tab>
</FlyoutItem>
</Shell>
In this example:
- ShellContent is the navigation entry.
- HomePage is the actual screen.
What is ShellContent?
A ShellContent is a Shell navigation item that hosts a Page. It does not contain the actual user interface.
Example
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:HomePage}" />
This tells Shell to display HomePage when the user navigates to this item.
Responsibilities of ShellContent
- Routing
- Navigation
- Tab creation
- Flyout menu entries
- Titles and Icons
- Deep-link navigation
What is a Page?
A Page is the actual screen that users interact with.
C# Example
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
}
}
XAML Example
<ContentPage>
<VerticalStackLayout>
<Label
Text="Welcome Home"
FontSize="30" />
</VerticalStackLayout>
</ContentPage>
Responsibilities of a Page
- User interface
- Layouts
- Controls
- Data binding
- Commands
- User interaction
- Business workflows
Example: ShellContent Hosting a Page
<Shell>
<TabBar>
<ShellContent
Route="home"
Title="Home"
ContentTemplate="{DataTemplate local:HomePage}" />
<ShellContent
Route="settings"
Title="Settings"
ContentTemplate="{DataTemplate local:SettingsPage}" />
</TabBar>
</Shell>
Navigation Structure:
TabBar
├── Home
│ └── HomePage
└── Settings
└── SettingsPage
ShellContent vs Page
ShellContent Handles
- Navigation configuration
- Routes
- Tab definitions
- Flyout definitions
- Titles and icons
Page Handles
- User interface
- Data display
- Forms
- Buttons
- Bindings
- User actions
ContentTemplate and Lazy Loading
The recommended approach is to use ContentTemplate.
Recommended
<ShellContent
ContentTemplate="{DataTemplate local:HomePage}" />
Not Recommended
<ShellContent>
<local:HomePage />
</ShellContent>
Using DataTemplate enables lazy loading. Pages are created only when needed, improving startup performance and memory usage.
Multiple ShellContents Inside a Tab
<Tab Title="Sales">
<ShellContent
Title="Orders"
ContentTemplate="{DataTemplate local:OrdersPage}" />
<ShellContent
Title="Invoices"
ContentTemplate="{DataTemplate local:InvoicesPage}" />
</Tab>
Structure:
Sales
├── Orders
└── Invoices
When to Use ShellContent
Use ShellContent for primary application navigation.
Examples
- Dashboard
- Home
- Customers
- Orders
- Reports
- Settings
Flyout Example
<FlyoutItem Title="Reports">
<ShellContent
ContentTemplate="{DataTemplate local:ReportsPage}" />
</FlyoutItem>
TabBar Example
<TabBar>
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:HomePage}" />
<ShellContent
Title="Profile"
ContentTemplate="{DataTemplate local:ProfilePage}" />
</TabBar>
When NOT to Use ShellContent
1. Modal Pages
Login pages, popup-style screens, and temporary flows should not normally be ShellContent items.
await Shell.Current.Navigation.PushModalAsync(
new LoginPage());
2. Workflow Screens
- Checkout Address
- Payment
- Confirmation
These typically should not appear in the Flyout or TabBar.
3. Wizard Pages
- Step 1
- Step 2
- Step 3
These are usually navigated programmatically instead of being ShellContent items.
ShellContent Route vs Registered Route
ShellContent Route
<ShellContent
Route="customers"
ContentTemplate="{DataTemplate local:CustomersPage}" />
Visible in the application's navigation structure.
Registered Route
Routing.RegisterRoute(
nameof(CustomerDetailsPage),
typeof(CustomerDetailsPage));
Navigation:
await Shell.Current.GoToAsync(
nameof(CustomerDetailsPage));
Registered routes are hidden from Flyout and TabBar navigation.
Best Practices
Use ShellContent Only for Main Navigation
Good:
- Home
- Customers
- Orders
- Reports
- Settings
Avoid:
- CustomerDetails
- EditCustomer
- EditInvoice
- PaymentConfirmation
Use ContentTemplate
<ShellContent
ContentTemplate="{DataTemplate local:HomePage}" />
Keep AppShell Focused on Navigation
AppShell should define navigation only. Business logic belongs in:
- Pages
- ViewModels
- Services
Register Detail Pages as Routes
Routing.RegisterRoute(
nameof(OrderDetailsPage),
typeof(OrderDetailsPage));
Use Meaningful Route Names
Good:
customers
orders
reports
settings
Avoid:
page1
page2
page3
Enterprise Application Example
AppShell
│
├── Dashboard
├── Shipments
├── Customers
├── Reports
├── Settings
│
└── Hidden Routes
├── ShipmentDetailsPage
├── CustomerEditPage
└── ReportViewerPage
Main sections use ShellContent. Detail and edit screens use registered routes.
Quick Rule of Thumb
Use ShellContent when a page should be part of the application's permanent navigation structure such as Flyout menus or bottom tabs.
Use a Page with a registered route when the page is temporary, detail-oriented, modal, or launched from another page.
Summary: ShellContent defines where a page appears in navigation, while the Page defines what the user sees and interacts with.
| MAUI-Headless-Pattern :👈 | 👉:MAUI Introduction |