Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
davidortinau avatar

Maui Shell Navigation

  • 45 installs
  • 163 repo stars
  • Updated July 6, 2026
  • davidortinau/maui-skills

Covers .NET MAUI Shell navigation including AppShell setup, tab bars, flyout menus, URI-based GoToAsync navigation, route registration, and query parameters.

About

Guides .NET MAUI Shell navigation covering the visual hierarchy, AppShell setup, tab bars, flyout menus, URI-based GoToAsync navigation, route registration and query parameters. A developer uses it when structuring navigation in a MAUI app with Shell.

  • AppShell setup with tab bars and flyout menus
  • URI-based GoToAsync navigation, route registration, and query parameters

Maui Shell Navigation by the numbers

  • 45 all-time installs (skills.sh)
  • Ranked #609 of 1,039 Mobile Development skills by installs in the Skillselion catalog
  • Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/davidortinau/maui-skills --skill maui-shell-navigation

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs45
repo stars163
Last updatedJuly 6, 2026
Repositorydavidortinau/maui-skills

What it does

Covers .NET MAUI Shell navigation including AppShell setup, tab bars, flyout menus, URI-based GoToAsync navigation, route registration, and query parameters.

Files

SKILL.mdMarkdownGitHub ↗

.NET MAUI Shell Navigation

Key decisions

ContentTemplate — always use it

Always use ContentTemplate with DataTemplate so pages are created on demand. Using Content directly creates all pages during Shell init, hurting startup time.

<!-- ✅ Lazy — page created on first navigation -->
<ShellContent ContentTemplate="{DataTemplate views:HomePage}" />

<!-- ❌ Eager — page created at Shell startup -->
<ShellContent>
    <views:HomePage />
</ShellContent>

Passing data — prefer IQueryAttributable over QueryProperty

IQueryAttributable gives you all parameters in one call and works on ViewModels:

public class AnimalDetailsViewModel : ObservableObject, IQueryAttributable
{
    public void ApplyQueryAttributes(IDictionary<string, object> query)
    {
        if (query.TryGetValue("id", out var id))
            AnimalId = id.ToString();
    }
}

For complex objects, use ShellNavigationQueryParameters to avoid serializing:

var parameters = new ShellNavigationQueryParameters
{
    { "animal", selectedAnimal }
};
await Shell.Current.GoToAsync("animaldetails", parameters);

Guarding navigation — async deferral pattern

Use GetDeferral() for async checks (e.g., "save unsaved changes?"):

protected override async void OnNavigating(ShellNavigatingEventArgs args)
{
    base.OnNavigating(args);
    if (hasUnsavedChanges && args.Source == ShellNavigationSource.Pop)
    {
        var deferral = args.GetDeferral();
        bool discard = await ShowConfirmationDialog();
        if (!discard)
            args.Cancel();
        deferral.Complete();
    }
}

Common gotchas

1. Duplicate route namesRouting.RegisterRoute throws ArgumentException if a route name is already registered or matches a visual hierarchy route. Every route must be unique across the entire app.

2. Relative routes require registration — you cannot GoToAsync("somepage") unless somepage was registered with Routing.RegisterRoute. Visual hierarchy pages use absolute // routes instead.

3. Pages are created on demand — when using ContentTemplate, the page constructor runs only on first navigation. Don't assume pages exist at startup.

4. Tab.Stack is read-only — you cannot manipulate the navigation stack directly; use GoToAsync for all navigation changes.

5. GoToAsync is async — always await it — fire-and-forget navigation causes race conditions and can silently fail:

   // ❌ Fire-and-forget — race conditions
   Shell.Current.GoToAsync("details");

   // ✅ Always await
   await Shell.Current.GoToAsync("details");

6. Route hierarchy matters — absolute routes must match the full path through the visual hierarchy (//FlyoutItem/Tab/ShellContent). Getting the path wrong produces silent no-ops, not exceptions.

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.