Skip to content

Getting Started

Introduction

Install BlazorPathHelper in your Blazor project.

Install BlazorPathHelper
1
dotnet add package BlazorPathHelper

URL Builder

Basic URL Builder

Create a file with the following content. You can name the file anything, but for explanation purposes, we'll call it WebPaths.cs.

WebPaths.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
using BlazorPathHelper;

// The BlazorPath attribute enables automatic generation.
// Also, make sure to declare the class as partial.
[BlazorPath]
public partial class WebPaths
{
  // Define URL pages as constants like this.
  // public const string (VariableName) = "/your-path";
  public const string Index = "/";
  public const string Sample = "/sample";
  public const string SampleChild = "/sample/child";
  public const string Counter = "/counter";
  public const string CounterWithState = "/counter/{count:int}";
  public const string CounterWithQuery = "/counter/query";
}

When defined this way, the following class definition is automatically generated.

Automatically Generated URL Builder
Auto Generated Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// <auto-generated />
public partial class WebPaths
{
  // A URL builder is generated in the Helper class
  public partial class Helper
  {
    public static string Index() => "/";
    public static string Sample() => "/sample";
    public static string SampleChild() => "/sample/child";
    public static string Counter() => "/counter";
    public static string CounterWithState(int Count)
      => string.Format("/counter/{0}", ToStringForUrl(Count));
    public static string CounterWithQuery() => "/counter/query";
  }
}

A URL builder that accepts an int parameter has been generated for WebPaths.Helper.CounterWithState. However, CounterWithQuery is not yet set up to accept queries because the query parameters have not been defined yet.

URL Builder with Query

Let's define it to accept queries.

WebPaths.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
using BlazorPathHelper;

[BlazorPath]
public partial class WebPaths
{
  public const string Index = "/";
  public const string Sample = "/sample";
  public const string SampleChild = "/sample/child";
  public const string Counter = "/counter";
  public const string CounterWithState = "/counter/{count:int}";
  [Query<QueryRecord>] // Specify the Query attribute like this
  public const string CounterWithQuery = "/counter/query";
}

// Define a class to accept query parameters.
// This class must be written in a .cs file. (See the note below)
// It is recommended to specify default values or make parameters nullable.
public record QueryRecord(string query = "hello", int page = 0, bool? opt = null);

Note!

The class definition for QueryRecord above will not be generated correctly if written in a .razor file. This is due to the nature of source generators. (Razor files are also converted to C# by source generators, which can cause conflicts.)

This will automatically generate the following class definition.

Automatically Generated URL Query Builder
Auto Generated Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// <auto-generated />
public partial class WebPaths
{
  public partial class Helper
  {
    // Common parts are omitted
    public static string CounterWithQuery(QueryRecord __query)
      => string.Format("/counter/query{0}", BuildQuery([
        ToEscapedStrings("query", __query.query),
        ToEscapedStrings("page", __query.page),
        ToEscapedStrings("opt", __query.opt)
      ]));
  }
}

Now, the URL builder for CounterWithQuery can accept queries. For more details on query definitions, refer to Query Support.

Usage

The URL builder function is (ClassName).Helper.(VariableName). You can use it as follows:

Usage.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Call the function to generate a URL
var homeUrl = WebPaths.Helper.Index();
// With parameters
var counterStateUrl = WebPaths.Helper.CounterWithState(1);
// With queries
var counterQueryUrl1 = WebPaths.Helper.CounterWithQuery(new());
var counterQueryUrl2 = WebPaths.Helper.CounterWithQuery(new() { query = "test" });
var counterQueryUrl3 = WebPaths.Helper.CounterWithQuery(new() { query = "foo", page = 1, opt = true });

Console.WriteLine(homeUrl);          // -> "/"
Console.WriteLine(counterStateUrl);  // -> "/counter/1"
Console.WriteLine(counterQueryUrl1); // -> "/counter/query?query=hello&page=0"
Console.WriteLine(counterQueryUrl2); // -> "/counter/query?query=test&page=0"
Console.WriteLine(counterQueryUrl3); // -> "/counter/query?query=foo&page=1&opt=true"

// To navigate to another page
// @inject NavigationManager Nav
Nav.NavigateTo(counterStateUrl);

For more detailed usage, refer to Using the URL Builder.

Automatic Page Attribute Specification

On the Blazor page side, you need to specify attributes like @page, [Parameter], and [SupplyParameterFromQuery], but these can also be automatically generated based on URL definition information.

WebPaths.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using BlazorPathHelper;
using Microsoft.AspNetCore.Components;

[BlazorPath]
public partial class WebPaths
{
  [Page<Home>] // <- Add the Page<PageComponent> attribute
  public const string Index = "/";
  [Page<Sample>]
  public const string Sample = "/sample";
  [Page<SampleChild>]
  public const string SampleChild = "/sample/child";
  [Page<Counter>]
  public const string Counter = "/counter";
  [Page<Counter2>]
  public const string CounterWithState = "/counter/{count:int}";
  [Page<Counter3>, Query<QueryRecord>]
  public const string CounterWithQuery = "/counter/query";
}

public record QueryRecord(string query = "hello", int page = 0, bool? opt = null);
// Definitions for each component (actually written in each component)
public partial class Home : ComponentBase;
public partial class Sample : ComponentBase;
public partial class SampleChild : ComponentBase;
public partial class Counter : ComponentBase;
public partial class Counter2 : ComponentBase;
public partial class Counter3 : ComponentBase;

This will automatically generate files that include class definitions with @page, [Parameter], and [SupplyParameterFromQuery].

Automatically Generated Page Definition File (Collapsible)
Auto Generated Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// <auto-generated />
// -------------------
// Index(Home)
[Route("/")] // Equivalent to writing [@page "/"] in a razor file
public partial class Home;

// Omitted for brevity

// CounterWithState(Counter2)
[Route("/counter/{count:int}")]
public partial class Counter2
{
  // Parameter definitions are automatically generated
  [Parameter]
  public int Count { get; set; }
}
// -------------------
// CounterWithQuery(Counter3)
[Route("/counter/query")]
public partial class Counter3
{
  // Query parameter definitions are automatically generated
  [SupplyParameterFromQuery]
  public string Query { get; set; }
  [SupplyParameterFromQuery]
  public int Page { get; set; }
  [SupplyParameterFromQuery]
  public bool? Opt { get; set; }
}

With this, page attributes are automatically set, eliminating the need to write them in .razor files. You can remove the @page attribute and others from .razor files. For detailed usage, refer to Automatic Page Attributes.

You Can Remove It Anytime

The automatic generation by the [Page] attribute is a completely independent feature. Therefore, if you don't need the automatic definitions, you can remove the [Page] attribute at any time.

Automatic Menu Structure Generation

Based on the URL definitions, menu structure data is also automatically generated. This is useful for dynamically creating menus.

Basic Menu Generation

Add the [Item] attribute to each URL definition.

WebPaths.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using BlazorPathHelper;

[BlazorPath]
public partial class WebPaths
{
  // The [Item("MenuName")] attribute enables automatic generation.
  // It is completely independent of the [Page]/[Query] attributes, so they can be used together.
  [Item("TopPage")]
  public const string Index = "/";
  [Item("Sample1a")]
  public const string Sample = "/sample";
  [Item("Sample1b")]
  public const string SampleChild = "/sample/child";
  [Item("Sample2a")]
  public const string Counter = "/counter";
  // Pages with parameters/queries should not be displayed in the menu, so the [Item] attribute is omitted.
  // (Even if set, they are automatically omitted from the menu)
  public const string CounterWithState = "/counter/{count:int}";
}

This will automatically generate menu structure data in WebPaths.MenuItem.

Automatically Generated Menu Structure Data (Collapsible)
Auto Generated Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// <auto-generated />
public partial class WebPaths
{
  public static readonly BlazorPathMenuItem[] MenuItem = [
    new BlazorPathMenuItem(){
      Name = "TopPage", // Menu name. If not specified, the variable name is used
      Path = "/",       // Page URL
      Children = []     // Submenu
      // There are several other properties that are automatically generated to help with menu creation.
    },
    new BlazorPathMenuItem(){
      Name = "Sample1a",
      Path = "/sample", 
      // Submenus are automatically generated based on the URL structure
      Children = [
        new BlazorPathMenuItem(){
          Name = "Sample1b",
          Path = "/sample/child", 
          Children = []
        }
      ]
    },
    new BlazorPathMenuItem(){
      Name = "Sample2a",
      Path = "/counter",
      Children = []
    }
  ]
}

Here, only the menu structure data is generated, and you need to implement the menu display separately. It's up to you which framework you use to create the menu!

For details, refer to the samples for each framework.

Customization

You can customize the menu generation with descriptions, icons, localization, and more. For details, refer to Menu Structure Customization.