FluentBlazorRouter 1.4.0

dotnet add package FluentBlazorRouter --version 1.4.0
                    
NuGet\Install-Package FluentBlazorRouter -Version 1.4.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="FluentBlazorRouter" Version="1.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FluentBlazorRouter" Version="1.4.0" />
                    
Directory.Packages.props
<PackageReference Include="FluentBlazorRouter" />
                    
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 FluentBlazorRouter --version 1.4.0
                    
#r "nuget: FluentBlazorRouter, 1.4.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 FluentBlazorRouter@1.4.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=FluentBlazorRouter&version=1.4.0
                    
Install as a Cake Addin
#tool nuget:?package=FluentBlazorRouter&version=1.4.0
                    
Install as a Cake Tool

FluentBlazorRouter

FluentBlazorRouter is an alternative router for blazor applications. It allows you to use dynamic groups and nesting instead of using hardcoded compile time constatnts to route to your amazing blazor pages. And all that without repeating yourself! (The future is now!)

NOTICE! This library was primarily written for .net 7 and 8

For a full working example see the net10example folder and its project.

If you are using .net 10 or newer just replacing the router in the App.razor file doens't work anymore. Instead you will need to add a single "RoutedPage" with an @page attribute (and also remove the layout from the new Routes.razor file or it will render that twice) like so:

@page "/"
@page "/{**path}"

@using FluentBlazorRouter

<FluentRouter>
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Not found</p>
        </LayoutView>
    </NotFound>
</FluentRouter>

@code {
    // not used but required
    [Parameter]
    public string Path { get; set; }
}

This page will essentially work like the old App.razor file and take care of routing. The rest is as explained below. 😃

Features

  • central route configuration, no more hopping around in multiple files
  • nested routes and groups/hierarchical routing
  • customizable route parameter parsing
  • route parameter type validation at application startup

Currently query parameters are not supported.

builtin route parameter types

Here are the builtin route parameter types:

  • string
  • long
  • int
  • short
  • byte
  • guid

You can extend these yourself in the IServiceCollection extension method. (See below)

Installation

You can simply install FluentBlazorRouter from nuget. Either via the command line or with your IDE of choice.

  dotnet add package FluentBlazorRouter

Usage/Examples

First of: you can remove all the @page directives in all blazor pages. You won't need them anymore. Also not on any new pages.

👋 Goodbye 👋

Now lets see how its done with FluentBlazorRouter.

Either add the following line into your _Imports.razor or directly in your App.razor file.

@using FluentBlazorRouter

Then in your App.razor replace the default Router with <FluentRouter>. It can be used as a drop in replacement.

It should look something like this:

@using FluentBlazorRouter 

<FluentRouter>
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
        <FocusOnNavigate RouteData="@routeData" Selector="h1"/>
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</FluentRouter>

Finally in your Program.cs file (in earlier versions this was in the Startup.cs file) you configure the router:

builder.Services.AddFluentRouting<FluentBlazorRouter.Test.Pages.Index>(rootBuilder => rootBuilder
    .WithPage<Counter>("counter/{Id:int}")
    .WithGroup("group/example", exampleGroupBuilder =>
    {
        exampleGroupBuilder.WithPage<FetchData>("fetchdata");
    }));

Note that pages can also have sub pages.

Route parameters can omit the type specifier, in which case they default to string. So "user/{UserName}" is equivalent to "user/{UserName:string}".

Getting the runtime route of a page

To get the route of a page at runtime simply inject a IRouteProvider instance and use one of the TryGetPageRoute methods.

Example from the Test project Counter.razor page:

@if (RouteProvider.TryGetPageRoute<Counter>(out var route))
{
    <p>relative url: @route</p>
}
else
{
    <p>how did you get here?</p>
}

Custom route parameter matchers

You can easily add your own custom route parameter matcher and parsers:

builder.Services.AddFluentRouting<FluentBlazorRouter.Test.Pages.Index>(...),// reduced for brevity
    optionsBuilder =>
    {
        optionsBuilder.AddSegmentMatcher("custom", new CustomMatcher());
    });

Router Middlewares

The router is capable of executing middlewares for additional routing decision making and logging. This can be used to implement custom validation and/or permission logic.

To add a middleware simply implement the IRouterMiddlware interface and make sure to call next() to execute the next middleware. Not calling next() will result in rendering the PageNotFound template.

public class MyMiddleware : IRouterMiddleware
{
    public void Execute(Action next, RouteData pageContext)
    {
        if (pageContext.PageType != typeof(FetchData))
        {
            next();
        }
    }
}

And this in your Program.cs:

builder.Services.AddTransient<IRouterMiddleware, MyMiddleware>();

Releasing

Releases are cut from a git tag and published to NuGet by GitHub Actions (just release 1.2.3). See RELEASING.md.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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 was computed.  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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.4.0 124 8/28/2026
1.3.1 113 8/28/2026
1.3.0 107 8/28/2026
1.3.0-rc.1 60 8/28/2026
1.2.2 103 8/27/2026
1.2.1 647 11/6/2022
1.1.0 629 5/9/2022
1.0.0 460 12/20/2021