Shell Navigation in .NET MAUI Step by step Implementation and Top 10 Questions and Answers
 Last Update: April 01, 2025      18 mins read      Difficulty-Level: beginner

Shell Navigation in .NET MAUI: A Detailed Guide

Navigation is a critical aspect of any modern mobile application, and .NET Multi-platform App UI (.NET MAUI) provides a robust framework to handle navigation through its powerful Shell component. Shell simplifies navigation by introducing a standardized way of navigating within an application, making it easier for developers to create intuitive and consistent user experiences across different platforms. In this guide, we will explore in detail how Shell navigation works in .NET MAUI, including important information and best practices.

What is Shell?

Shell is a specialized navigation container that provides a standard structure for common application patterns. It allows developers to create applications with tabs, flyouts, and other navigation components, without having to implement this functionality from scratch. Shell simplifies the process of creating multi-page applications, making it easier to build complex navigation scenarios.

Key Components of Shell Navigation

Shell in .NET MAUI consists of several key components that work together to provide a seamless navigation experience:

  1. Flyout: A side menu that can be accessed by swiping from the left of the screen or tapping a hamburger icon. It is typically used for navigation between major sections of the application.
  2. Tabs: Horizontal tabs displayed at the bottom of the screen, allowing users to switch between different pages or sections of a specific area within the application.
  3. Routes: URL-like paths used to navigate between pages. Routes make it easy to navigate to a specific page using a simple string, rather than having to instantiate the page manually.
  4. Layouts: Shell provides default layouts that can be customized to fit the needs of the application. These layouts include flyout, bottom tabs, and top tabs.
  5. ShellContent: Represents a page or a group of pages within a tab. It is used to define the content that will be displayed when a tab is selected.

Setting Up Shell Navigation

To set up Shell navigation in a .NET MAUI application, follow these steps:

  1. Create a New .NET MAUI Project: Open Visual Studio and create a new .NET MAUI project. Visual Studio provides a default structure that includes a AppShell.xaml file, which is the main entry point for Shell navigation.
  2. Define the Shell Structure: Use XAML to define the structure of your application. For example, you can define a flyout and tabs within the AppShell.xaml file.
  3. Register Routes: Use the Routing.RegisterRoute method to define routes for your pages. This makes it easy to navigate to a page using a route, rather than having to instantiate the page manually.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       x:Class="MyApp.AppShell">

    <Shell.FlyoutHeader>
        <!-- Define the flyout header -->
    </Shell.FlyoutHeader>

    <Shell.FlyoutItems>
        <Shell.FlyoutItem Title="Home" Icon="home.png" Route="home" />
        <Shell.FlyoutItem Title="Settings" Icon="settings.png" Route="settings" />
    </Shell.FlyoutItems>

    <TabBar>
        <Tab Title="Browse" Icon="tab_feed.png">
            <ShellContent ContentTemplate="{DataTemplate local:ItemsPage}" Route="browseroute" />
        </Tab>
        <Tab Title="About" Icon="tab_about.png">
            <ShellContent ContentTemplate="{DataTemplate local:AboutPage}" Route="aboutroute" />
        </Tab>
    </TabBar>
</Shell>

Navigating Between Pages

Navigation in Shell can be performed using routes, which are simple string paths that correspond to specific pages. You can navigate between pages in several ways:

  1. Using the GoToAsync Method: You can use the GoToAsync method to navigate to a specific page by its route.
await Shell.Current.GoToAsync("home");
  1. Using the Shell.Current Property: You can also use the Shell.Current property to navigate to a specific page.
await Shell.Current.GoToAsync($"{nameof(AboutPage)}");
  1. Using Data Binding and Commanding: Shell supports data binding and commanding, which allows you to navigate to a specific page using commands.
private async void NavigateToSettings(object obj)
{
    await Shell.Current.GoToAsync("settings");
}
  1. Using Query Parameters: You can pass query parameters to a page using routes. This allows you to pass data to a page when navigating.
await Shell.Current.GoToAsync($"home?param1=value1&param2=value2");
  1. Using Modal Navigation: Shell supports modal navigation, which allows you to display a page as a modal dialog.
await Shell.Current.GoToAsync(nameof(MyModalPage));

Best Practices for Shell Navigation

  1. Define Clear Routes: Use clear and descriptive routes for your pages. This makes it easier to navigate between pages and improves code readability.
  2. Group Related Pages: Group related pages together using tabs or flyout items. This makes it easier for users to find the information they need.
  3. Use Query Parameters: Use query parameters to pass data between pages. This avoids the need to pass data through constructors or static fields.
  4. Handle Navigation Parameters: Handle navigation parameters in the OnNavigatedTo method of your pages. This allows you to initialize your pages with the correct data.
  5. Use Modal Navigation for Tasks: Use modal navigation for tasks that require the user's attention, such as editing a profile or creating a new item.

In conclusion, Shell navigation in .NET MAUI provides a powerful and flexible way to handle navigation within your application. By understanding the key components of Shell and following best practices, you can create intuitive and consistent navigation experiences for your users. Whether you're building a simple application or a complex multi-page application, Shell provides the tools and features you need to create a polished and professional user experience.

Shell Navigation in .NET MAUI: Step-by-Step Examples

Shell navigation is a powerful feature offered by .NET Multi-platform App UI (.NET MAUI) that simplifies the navigation structure in your application by providing a simple and declarative way to define the navigation hierarchy. Shell integrates the features like tabs, flyout menus, and URI-based navigation in a single, cohesive framework. Here, we will go through a detailed walkthrough to help beginners understand how to set up Shell navigation and manage data flow in a .NET MAUI application.

Step 1: Setting Up a .NET MAUI Project

First, ensure you have the latest version of Visual Studio with the .NET MAUI workload installed. Start a new .NET MAUI project by selecting "Multi-platform App (.NET MAUI)" from the list of templates.

Create a new .NET MAUI project

Follow the prompts to create a new project with the default settings.

Step 2: Setting Up the Shell Structure

When you create a new .NET MAUI project, a Shell class is automatically added to the project, typically named AppShell.xaml. Open AppShell.xaml from your project and you'll see an XML structure that looks like the following:

<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       x:Class="YourAppName.AppShell">
    <ShellContent>
        <ShellContent.Title>Home</ShellContent.Title>
        <ShellContent.ContentTemplate>
            <DataTemplate>
                <local:MainPage />
            </DataTemplate>
        </ShellContent.ContentTemplate>
    </ShellContent>
</Shell>

This example has a single ShellContent element. Let's add more tabs by adding more ShellContent elements. Here's an example with a tabbed navigation layout:

<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       x:Class="YourAppName.AppShell"
       Title="MyApp">

    <!-- Tab 1: Home -->
    <TabBar>
        <ShellContent Title="Home"
                      Icon="icon_home.png">
            <ShellContent.ContentTemplate>
                <DataTemplate>
                    <local:MainPage />
                </DataTemplate>
            </ShellContent.ContentTemplate>
        </ShellContent>

        <!-- Tab 2: Settings -->
        <ShellContent Title="Settings"
                      Icon="icon_settings.png">
            <ShellContent.ContentTemplate>
                <DataTemplate>
                    <local:SettingsPage />
                </DataTemplate>
            </ShellContent.ContentTemplate>
        </ShellContent>
    </TabBar>
</Shell>

Step 3: Creating Pages

Ensure you have the MainPage.xaml and SettingsPage.xaml defined. Use Visual Studio's context menu to add new content pages to your project. These pages will serve as the views for the tabs you defined in the AppShell.xaml.

Here is a simple MainPage.xaml:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="YourAppName.MainPage">

    <StackLayout Padding="20">
        <Label Text="Welcome to the Home Page!" 
               HorizontalTextAlignment="Center" 
               FontSize="Title" />
    </StackLayout>
</ContentPage>

Similarly, SettingsPage.xaml:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="YourAppName.SettingsPage">

    <StackLayout Padding="20">
        <Label Text="This is the Settings Page"
               HorizontalTextAlignment="Center"
               FontSize="Title" />
    </StackLayout>
</ContentPage>

Step 4: Running the Application

Run the application by pressing F5 or by selecting "Start Debugging" from the toolbar. Visual Studio will build and deploy the application to your default emulator. Once the app launches, you should see the Home tab active, with the settings tab available to switch to via the tab bar.

Step 5: Data Flow in Shell Navigation

Data flow in .NET MAUI applications is often managed through view models and data services. However, for simplicity, let's demonstrate a basic navigation with data passing between pages.

First, create a model class:

public class UserData
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Modify the MainPage.xaml.cs to hold and pass a UserData object:

private UserData userData;

public MainPage()
{
    InitializeComponent();
    userData = new UserData { Name = "John Doe", Age = 30 };
}

private async void OnNavigateToSettings(object sender, EventArgs e)
{
    await Shell.Current.GoToAsync(nameof(SettingsPage), new Dictionary<string, object>
    {
        { "userData", userData }
    });
}

In SettingsPage.xaml.cs, retrieve and display the UserData object:

protected override async void OnNavigatedTo(NavigatedToEventArgs args)
{
    base.OnNavigatedTo(args);
    UserData userData = (UserData)args.Parameters["userData"];

    // Assuming a Label named "lblUserData" in SettingsPage.xaml
    lblUserData.Text = $"Name: {userData.Name}, Age: {userData.Age}";
}

To trigger navigation from MainPage, add a button and bind it to the OnNavigateToSettings event:

<Button Text="Go to Settings"
        Clicked="OnNavigateToSettings" />

Summary

In this guide, we created a .NET MAUI application with tabbed navigation using Shell. We also demonstrated how to pass and handle data across different pages. This example serves as a starting point for more complex navigation scenarios and data management in .NET MAUI apps. Shell navigation is a powerful feature that can significantly simplify the user interface and navigation hierarchy of your applications. Happy coding!

Top 10 Questions and Answers: Shell Navigation in .NET MAUI

1. What is a Shell in .NET MAUI and why should I use it?

Answer: In .NET Multi-platform App UI (.NET MAUI), a Shell is a foundational application layout provided to simplify the creation of multi-page applications, particularly those that require a tab bar or flyout menu for navigation. Shell offers a modern and consistent user experience across platforms (iOS, Android, macOS, and Windows) by providing pre-built navigation patterns. Using Shell, you can easily manage page hierarchies, handle navigation, and apply styles and templates uniformly to your app. It simplifies the process of setting up complex navigation structures without the need for custom page navigation logic, which can help speed up development and maintain a clean, organized codebase.


2. How do I install and set up Shell in a .NET MAUI application?

Answer: Setting up Shell in a .NET MAUI application is straightforward. When you create a new project, you can opt to use the .NET MAUI Shell template, which automatically includes the necessary structure. If you are starting from an existing project, you can manually add Shell as follows:

  1. Remove the MainPage assignment in your App.xaml.cs.
  2. Create a new XAML file for your Shell, typically named AppShell.xaml.
  3. In AppShell.xaml, set the root element to Shell and define your routes or tabs.
  4. Set the MainPage in App.xaml.cs to be an instance of AppShell.

Here is a basic setup:

<!-- AppShell.xaml -->
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       x:Class="YourApp.AppShell">
    <ShellItem Title="Home">
        <ShellSection>
            <ShellContent ContentTemplate="{DataTemplate local:MainPage}" />
        </ShellSection>
    </ShellItem>
</Shell>
// App.xaml.cs
public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        MainPage = new AppShell();
    }
}

3. How do I navigate to a different page using Shell navigation in .NET MAUI?

Answer: Navigating to a different page using Shell in .NET MAUI can be done via XAML or code-behind. Here’s how you can achieve both:

XAML:

You can use Shell.Href to navigate from a hyperlink or directly in commands.

<Button Text="Navigate to Details"
        NavigateTo="details" />

<!-- AppShell.xaml -->
<ShellRoute Route="details" View="DetailsPage" />

Code-Behind:

Use Shell.Current.GoToAsync to programmatically navigate:

private async void OnNavigateButtonClicked(object sender, EventArgs e)
{
    await Shell.Current.GoToAsync("details");
}

4. How can I include a tabbed interface in my .NET MAUI application using Shell?

Answer: To include a tabbed interface using Shell, you define ShellItem elements within the Shell. Each ShellItem contains one or more ShellSection elements, and each ShellSection contains ShellContent. Here is an example of how to set up a simple tabbed interface:

<!-- AppShell.xaml -->
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       x:Class="YourApp.AppShell">

    <ShellItem Title="Home" FlyoutDisplayOptions="AsMultipleItems">
        <ShellSection>
            <ShellContent Title="Home" Icon="home.png" ContentTemplate="{DataTemplate local:MainPage}" Route="home" />
        </ShellSection>
    </ShellItem>

    <ShellItem Title="Settings" FlyoutDisplayOptions="AsMultipleItems">
        <ShellSection>
            <ShellContent Title="Settings" Icon="settings.png" ContentTemplate="{DataTemplate local:SettingsPage}" Route="settings" />
        </ShellSection>
    </ShellItem>

</Shell>

In this example, "Home" and "Settings" are the tabs accessible via a bottom tab bar.


5. How can I implement a flyout (hamburger menu) in .NET MAUI using Shell?

Answer: To implement a flyout menu in .NET MAUI using Shell, you need to define ShellItem elements within the Shell with a FlyoutDisplayOptions attribute set to AsMultipleItems or AsSingleItem. Here’s an example:

<!-- AppShell.xaml -->
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       x:Class="YourApp.AppShell">

    <FlyoutItem Title="Home" Icon="home.png" Route="home">
        <ShellContent ContentTemplate="{DataTemplate local:MainPage}" />
    </FlyoutItem>

    <FlyoutItem Title="Settings" Icon="settings.png" Route="settings">
        <ShellContent ContentTemplate="{DataTemplate local:SettingsPage}" />
    </FlyoutItem>

</Shell>

This XML snippet adds "Home" and "Settings" to a flyout menu. The FlyoutItem elements automatically generate the hamburger menu and handle navigation based on the Route attribute.


6. How can I pass parameters during navigation in .NET MAUI with Shell?

Answer: You can pass parameters during navigation using Shell in .NET MAUI by appending query string parameters to the route. On the destination page, you can access these parameters using the OnNavigatedTo method or by implementing IQueryAttributable.

Example:

Navigating with Parameters:

await Shell.Current.GoToAsync($"details?name={name}&age={age}");

Handling Parameters on the Destination Page:

// In DetailsPage.xaml.cs
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
    if (args.Parameters.TryGetValue("name", out var name))
    {
        // Use the name value
    }
    if (args.Parameters.TryGetValue("age", out var age))
    {
        // Use the age value
    }
    base.OnNavigatedTo(args);
}

Alternatively, you can implement IQueryAttributable:

public class DetailsPage : ContentPage, IQueryAttributable
{
    public void ApplyQueryAttributes(IDictionary<string, object> query)
    {
        if (query.ContainsKey("name"))
        {
            string name = query["name"].ToString();
            // Use the name value
        }
        if (query.ContainsKey("age"))
        {
            string age = query["age"].ToString();
            // Use the age value
        }
    }
}

7. How can I handle nested navigation in a .NET MAUI Shell application?

Answer: Handling nested navigation in .NET MAUI Shell involves defining a hierarchy of ShellItem, ShellSection, and ShellContent elements. You can have multiple levels of nested pages by using Shell routes that include segments. Here is an example:

<!-- AppShell.xaml -->
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       x:Class="YourApp.AppShell">

    <TabBar>
        <Tab Title="Home">
            <ShellContent ContentTemplate="{DataTemplate local:MainPage}" Route="home" />
        </Tab>
        <Tab Title="Products">
            <ShellContent ContentTemplate="{DataTemplate local:ProductsPage}" Route="products" />
        </Tab>
    </TabBar>

    <FlyoutItem Title="Orders" Icon="orders.png" Route="orders">
        <ShellContent ContentTemplate="{DataTemplate local:OrdersPage}" />
    </FlyoutItem>

</Shell>

In this example, "Products" and "Orders" are top-level navigation items. To navigate to a nested page within "Products," you can define a route like "products/details" and use Shell.Current.GoToAsync("products/details").


8. How can I customize the appearance and behavior of the Shell in .NET MAUI?

Answer: Customizing the appearance and behavior of the Shell in .NET MAUI can be done through various properties and styles. Here are some common customizations:

Setting Titles and Icons:

<Tab Title="Home" Icon="home.png">
    <ShellContent ContentTemplate="{DataTemplate local:MainPage}" />
</Tab>

Applying Styles:

Define styles in App.xaml and apply them to Shell elements:

<!-- App.xaml -->
<Application.Resources>
    <Style TargetType="Shell">
        <Setter Property="BackgroundColor" Value="#F5F5F5" />
        <Setter Property="NavigationPage.BarBackgroundColor" Value="#007acc" />
        <Setter Property="NavigationPage.BarTextColor" Value="White" />
    </Style>
</Application.Resources>

Customizing Flyout:

Override or define custom templates for the flyout:

<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       x:Class="YourApp.AppShell">

    <FlyoutHeader>
        <StackLayout BackgroundColor="#007acc">
            <Image Source="logo.png" HeightRequest="60" WidthRequest="60" />
            <Label Text="My App" FontSize="Large" TextColor="White" Margin="10" />
        </StackLayout>
    </FlyoutHeader>

    <!-- Define Flyout Items -->

</Shell>

9. How can I use the Back button behavior with Shell in .NET MAUI?

Answer: Shell in .NET MAUI automatically handles the back button behavior for you, but you can customize it if needed. Here are some ways to manage back button behavior:

Preventing Back Navigation:

protected override bool OnBackButtonPressed()
{
    // Return true to prevent the back button from working
    return true;
}

Handling Back Button Events:

Override the OnBackButtonPressed method in your page to handle back button events:

protected override void OnAppearing()
{
    base.OnAppearing();
    Shell.Current.Navigating += OnNavigating;
}

protected override void OnDisappearing()
{
    base.OnDisappearing();
    Shell.Current.Navigating -= OnNavigating;
}

private void OnNavigating(object sender, ShellNavigatingEventArgs e)
{
    if (e.CanCancel)
    {
        // Customize behavior before navigation
    }
}

Managing Back Stack:

You can use Shell.Current.Navigation.PopAsync to navigate back programmatically.

private async void OnBackButtonClicked(object sender, EventArgs e)
{
    await Shell.Current.Navigation.PopAsync();
}

10. What are the best practices for using Shell in .NET MAUI applications?

Answer: Here are some best practices for using Shell in .NET MAUI applications:

Consistent Navigation:

  • Use consistent navigation patterns across your app to provide a seamless user experience.

Simplified Navigation Code:

  • Leverage Shell’s built-in navigation methods to keep your code clean and manageable.

Customize Shell Appropriately:

  • Customize Shell’s appearance and behavior, but avoid overcomplicating the design to the point where it detracts from the user experience.

Use Hierarchical Routes:

  • Define routes in a hierarchical manner to make navigation straightforward and maintainable.

Handle Edge Cases:

  • Implement back button behavior and handle edge cases, such as navigating back from a nested page, carefully to ensure a robust application.

Optimize Performance:

  • Keep nested navigation shallow to avoid performance issues. If necessary, use lazy loading for pages to improve startup time.

Adapt to Platform Differences:

  • Although Shell provides a unified experience, test your application on all target platforms to ensure it behaves as expected. Adjust the flyout and tab bar designs to fit platform-specific conventions.

By following these best practices, you can effectively use Shell in .NET MAUI to create modern, efficient, and intuitive multi-platform applications.