Navs 2.1.0

dotnet add package Navs --version 2.1.0
                    
NuGet\Install-Package Navs -Version 2.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Navs" Version="2.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Navs" Version="2.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Navs" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Navs --version 2.1.0
                    
#r "nuget: Navs, 2.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Navs@2.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Navs&version=2.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Navs&version=2.1.0
                    
Install as a Cake Tool

The Navs Family

Navs is a router family for .NET applications. The core library is UI-agnostic; the adapters bind it to Avalonia, FuncUI and Terminal.Gui.

  • Navs — core router, route table, guards, history and cache.
  • UrlTemplates — URL and route-pattern parsing.
  • Navs.Avalonia — Avalonia controls.
  • Navs.FuncUI — Avalonia.FuncUI components.
  • Navs.Terminal.Gui — Terminal.Gui controls.
  • Navs.Goo — Goo Blob routes and a Cell outlet.
  • Navs.CSharp — C#-friendly facade.
  • UrlTemplates.CSharp — C#-friendly facade for URL templates.
open System
open System.Threading
open Navs
open Navs.Router

let routes = [
    Route.define<string>("home", "/", fun _ _ -> "Home")
    Route.define<string>("about", "/about", fun _ _ -> "About")
    Route.define<string>(
        "guid",
        "/:id<guid>",
        fun context _ -> async {
            do! Async.Sleep 90
            return
                match context.GetParam<Guid>("id") with
                | ValueSome id -> $"Guid {id}"
                | ValueNone -> "No GUID"
        }
    )
]

let router =
    match Router.createDefault(routes) with
    | Ok router -> router
    | Error errors -> invalidOp $"Invalid routes: %A{errors}"

let result =
    router.Navigate("/about") CancellationToken.None
    |> fun task -> task.GetAwaiter().GetResult()

match result with
| Ok _ -> printfn "Current view: %A" router.Snapshot.Content
| Error error -> printfn "Navigation failed: %A" error

Navigate returns a CancellableTask<Result<...>>. Pass the token when you invoke it. The router exposes its current state through router.Snapshot and publishes changes through router.Changed.

using Navs.CSharp;

var routes = new[]
{
    Route.Define<string>("home", "/", (context, navigable) => "Home"),
    Route.Define<string>("about", "/about", (context, navigable) => "About")
};

var router = Router.Create(routes);
var outcome = await router.NavigateAsync("/about");

if (outcome.IsSuccess)
{
    Console.WriteLine(router.Snapshot.Content);
}
else
{
    Console.WriteLine(outcome.Error?.Code);
}

C# receives NavigationOutcome; it does not need to handle F# Result or ValueOption. TryBuildLink and IsActive generate links and answer active-route questions, and TryGetParam<T>/GetParamValues<T> read typed parameters from the route context or the snapshot.

open System.Threading
open Avalonia.Controls
open Navs
open Navs.Router
open Navs.Avalonia

let block text =
    let value = TextBlock()
    value.Text <- text
    value :> Control

let routes = [
    Route.define<Control>("home", "/", fun _ _ -> block "Home")
    Route.define<Control>("about", "/about", fun _ _ -> block "About")
]

let router = AvaloniaRouter(routes) :> IRouter<Control>

let outlet = RouterOutlet()
outlet.Router <- Some router

router.Navigate("/") CancellationToken.None |> ignore
open Avalonia.FuncUI.DSL
open Avalonia.FuncUI.Types
open Navs
open Navs.Router
open Navs.FuncUI

let routes = [
    Route.define<IView>("books", "/books", fun _ _ -> TextBlock.create [])
    Route.define<IView>("about", "/about", fun _ _ -> TextBlock.create [])
]

let router = FuncUIRouter(routes) :> IRouter<IView>
let outlet = RouterOutlet.create(router)
open Terminal.Gui.Views
open Navs
open Navs.Router
open Navs.Terminal.Gui

let routes = [
    Route.define<Window>("home", "/", fun _ _ -> Window())
    Route.define<Window>("about", "/about", fun _ _ -> Window())
]

let router = TerminalGuiRouter(routes) :> IRouter<Window>
let outlet = RouterOutlet(router)

Navs.Goo binds the core router to Goo Blob values. A route returns a fresh Blob tree. A route that needs state returns a Cell.Mount blob with a factory and a key, so Goo keeps Cell ownership and disposal.

open Goo
open Navs
open Navs.Router
open Navs.Goo

let routes = [
    Route.define<Blob>("home", "/", fun _ _ -> Text(Content = "Home") :> Blob)
    Route.define<Blob>("about", "/about", fun _ _ -> Text(Content = "About") :> Blob)
]

let router = GooRouter(routes) :> IRouter<Blob>
let outlet = new RouterOutlet(initialUri = "/")
outlet.Router <- Some router

let window = Window(Title = "Navs.Goo", Width = 720, Height = 480, Root = outlet)
outlet.Window <- Some window
window.Run()

UrlTemplates

UrlTemplates parses URL templates and URLs. Navs compiles route patterns at router creation, so matching does not reparse templates on every navigation.

open UrlTemplates.RouteMatcher

let template = "/api/v1/profiles/:id<int>?optionalKey<guid>&requiredKey!#hash"
let url = "/api/v1/profiles/2345?requiredKey=2#hash"

match RouteMatcher.matchStrings template url with
| Ok (parsedTemplate, urlInfo, urlMatch) ->
    printfn "%A" parsedTemplate
    printfn "%A" urlInfo
    printfn "%A" urlMatch
| Error errors -> printfn "%A" errors

UrlTemplates (C#)

UrlTemplates.CSharp exposes the same operations through Try... methods, typed parameters and structured errors, with no F# types in the signatures.

using UrlTemplates.CSharp;

if (UrlTemplate.TryParse("/api/v1/profiles/:id<int>", out var template, out var templateError))
{
    if (RouteMatcher.TryMatch(template!, "/api/v1/profiles/2345", out var match, out var errors))
    {
        match!.TryGetPathParam<int>("id", out var id);
        Console.WriteLine(id); // 2345
    }
}
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (5)

Showing the top 5 NuGet packages that depend on Navs:

Package Downloads
Navs.Avalonia

Package Description

Navs.FuncUI

Package Description

Navs.Terminal.Gui

Package Description

Navs.CSharp

Package Description

Navs.Goo

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.0 126 11/10/2026
2.0.1 249 10/18/2026
2.0.0 150 10/18/2026
1.0.1 151 10/17/2026
1.0.0 257 6/25/2026
1.0.0-rc-008 555 6/17/2025
1.0.0-rc-007 309 6/4/2025
1.0.0-rc-006 306 5/16/2025
1.0.0-rc-005 335 11/30/2024
1.0.0-rc-004 238 11/27/2024
1.0.0-rc-003 242 11/14/2024
1.0.0-rc-002 230 11/13/2024
1.0.0-rc-001 361 3/28/2024
1.0.0-beta-008 260 3/17/2024
1.0.0-beta-007 257 3/15/2024
1.0.0-beta-006 239 3/13/2024
1.0.0-beta-005 257 3/10/2024
1.0.0-beta-004 261 3/9/2024
1.0.0-beta-003 263 3/7/2024
1.0.0-beta-002 247 3/6/2024
Loading failed

### Added

- **Navs.Goo:** New Goo adapter with `GooRouter` for `Blob` routes and a `RouterOutlet` Cell that renders the active route, marshals change notices to the UI thread with `Window.Post`, and keeps route and navigation error text intact in native builds.
- **Samples:** New `GooSample` app with Home, Counter, and About routes that follows the system light or dark Goo theme.