Navs 2.1.0
dotnet add package Navs --version 2.1.0
NuGet\Install-Package Navs -Version 2.1.0
<PackageReference Include="Navs" Version="2.1.0" />
<PackageVersion Include="Navs" Version="2.1.0" />
<PackageReference Include="Navs" />
paket add Navs --version 2.1.0
#r "nuget: Navs, 2.1.0"
#:package Navs@2.1.0
#addin nuget:?package=Navs&version=2.1.0
#tool nuget:?package=Navs&version=2.1.0
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— GooBlobroutes and aCelloutlet.Navs.CSharp— C#-friendly facade.UrlTemplates.CSharp— C#-friendly facade for URL templates.
Navs (F#)
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.
Navs (C#)
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.
Navs.Avalonia
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
Navs.FuncUI
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)
Navs.Terminal.Gui
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
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 | Versions 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. |
-
net10.0
- FSharp.Core (>= 10.0.103)
- FsToolkit.ErrorHandling (>= 5.2.0)
- IcedTasks (>= 0.11.9)
- Microsoft.Extensions.Logging (>= 10.0.9)
- UrlTemplates (>= 2.1.0)
-
net8.0
- FSharp.Core (>= 9.0.100)
- FsToolkit.ErrorHandling (>= 5.2.0)
- IcedTasks (>= 0.11.9)
- Microsoft.Extensions.Logging (>= 10.0.9)
- UrlTemplates (>= 2.1.0)
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 |
### 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.