This guide walks through the smallest useful RouteNav.Avalonia setup: install the package, bootstrap the UI platform, register pages, create a stack and navigate by URI.
dotnet add package RouteNav.AvaloniaRouteNav.Avalonia targets Avalonia 12 and .NET 10.
Include RouteNav styles in your application styles. In most projects this goes in App.axaml alongside your Avalonia theme:
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.App">
<Application.Styles>
<FluentTheme />
<StyleInclude Source="avares://RouteNav.Avalonia/Themes/RouteNavStyles.axaml" />
</Application.Styles>
</Application>Use UseRouteNavUIPlatform(...) while building the Avalonia app. The base route URI is used to resolve absolute internal routes.
public static AppBuilder BuildAvaloniaApp() =>
AppBuilder.Configure<App>()
.UsePlatformDetect()
.UseRouteNavUIPlatform(
"https://myapp.local/",
() => Services.BuildServiceProvider(),
Services);If your app uses a single object that implements both IServiceCollection and IServiceProvider, you can use the generic overload:
builder.UseRouteNavUIPlatform("https://myapp.local/", container);If you provide a custom platform implementation, use:
builder.UseRouteNavUIPlatform("https://myapp.local/", myUiPlatform);RouteNav uses its own RouteNav.Avalonia.Window abstraction so the same code works for desktop windows, mobile single views and browser views.
public override void OnFrameworkInitializationCompleted()
{
base.OnFrameworkInitializationCompleted();
#if DEBUG
this.AttachDeveloperTools();
#endif
ApplicationLifetime.SetMainWindow(new MainWindow());
}On desktop, this creates an Avalonia Window. On mobile/browser, it creates the appropriate top-level view. On Avalonia 12 Android, RouteNav wires the activity lifetime through IActivityApplicationLifetime.MainViewFactory.
A RouteNav page derives from RouteNav.Avalonia.Page.
public partial class HomePage : Page
{
public HomePage()
{
InitializeComponent();
Title = "Home";
}
}Pages can be defined in XAML or code. Each page has:
Title- used by navigation bars, tabs and dialogs.PageQuery- query-string parameters parsed from the route URI.DialogSizeHint- default size hint when shown as a dialog.SafeAreaPadding- propagated from platform safe-area insets.
Register page types during app initialization. This enables DI construction and query injection.
Navigation.UIPlatform.RegisterPage<HomePage, DetailsPage, SettingsPage>();You can also register pages directly with your DI container and then resolve them through a custom page factory or IPageResolver.
A stack maps URI routes to pages and owns the current navigation container.
var mainStack = new NavigationPageStack(Navigation.MainStackName, "My App");
Navigation.UIPlatform.AddStack(mainStack);
mainStack.AddPage<HomePage>(String.Empty);
mainStack.AddPage<DetailsPage>("details");
mainStack.AddPage<SettingsPage>("settings");The empty route (String.Empty) is the root page of the stack.
Navigate with a URI:
await Navigation.PushAsync(new Uri("https://myapp.local/main/details"));Or use a stack name and relative route:
await Navigation.PushAsync("main", "details");Or use a routing control in XAML:
<routing:RouteButton RoutePath="/main/details" Content="Open details" />Route query strings are parsed into Page.PageQuery.
await Navigation.PushAsync(new Uri("https://myapp.local/main/details?id=42&mode=edit"));if (PageQuery.TryGetValue("id", out var id))
{
// use id
}RouteNav also adds a routeUri entry containing the full resolved route URI.
Any page can be displayed as a dialog:
await Navigation.PushAsync(
new Uri("https://myapp.local/main/details?id=42"),
NavigationTarget.Dialog);Or explicitly:
var result = await MessageDialog
.Create("Confirm", "Continue?", MessageDialogButtons.OkCancel)
.ShowDialog(this);- Read Concepts for the mental model.
- Read Navigation Stacks to choose the right layout.
- Read Routing for URI and target behavior.