Helper class to enable url change on Blazor tab index change and mapping url to Blazor tab index.
Nuget package: https://www.nuget.org/packages/ShahJe.Blazor.NavigationTab
Currently supports Radzen Tabs.
Targets .NET 8, .NET 9 and .NET 10. The only dependency is Microsoft.AspNetCore.Components,
so it works in Blazor Server and Blazor WebAssembly alike. Reference Radzen.Blazor yourself
for the tab control — 2.0 no longer pulls it in for you.
Sync works in both directions:
- selecting a tab pushes its mapped url
- navigating to a mapped url selects the matching tab, whether that navigation came from the address bar, an in-app link, or the browser back/forward buttons
Following code snippet shows how to setup:
@page "/radzentab"
@page "/radzentab/tab2"
@page "/radzentab/tab3"
@implements IDisposable
@inject NavigationManager NavigationManager
<h1>Radzen Blazor Navigation Tab Demo</h1>
<RadzenTabs SelectedIndex="@NavigationTab.TabIndex" Change="@NavigationTab.TabIndexChanged">
<Tabs>
<RadzenTabsItem Text="Tab 1">
<p>This is tab1</p>
</RadzenTabsItem>
<RadzenTabsItem Text="Tab 2">
<p>This is tab2</p>
</RadzenTabsItem>
<RadzenTabsItem Text="Tab 3">
<p>This is tab3</p>
</RadzenTabsItem>
</Tabs>
</RadzenTabs>
@code {
private NavigationTab NavigationTab { get; set; }
protected override void OnInitialized()
{
NavigationTab = new NavigationTab(
"/radzentab",
new Dictionary<int, string>
{
{ 0, "" },
{ 1, "/tab2" },
{ 2, "/tab3" }
},
NavigationManager);
// Navigation happens outside the component's render cycle, so it has to be told.
NavigationTab.Changed += OnTabChangedByNavigation;
}
private void OnTabChangedByNavigation()
{
InvokeAsync(StateHasChanged);
}
public void Dispose()
{
if (NavigationTab is null)
{
return;
}
NavigationTab.Changed -= OnTabChangedByNavigation;
NavigationTab.Dispose();
}
}
Two things are required for url changes to select a tab:
- Subscribe to
Changedand callStateHasChanged. A url-driven tab change happens outside the component's render cycle, so the component will not re-render on its own. - Dispose the
NavigationTab. It subscribes toNavigationManager.LocationChanged, and leaking that subscription keeps the component alive.
See sample app ShahJe.Blazor.NavigationTab.Sample for a working example.
1.x only selected a tab on a full page load, so in-app links and browser back/forward left the tab and the url out of sync. Fixing that changed the API:
| 1.x | 2.0 |
|---|---|
NavigationTab had no lifetime |
implements IDisposable — the component must dispose it |
| no change notification | Changed event — subscribe and call StateHasChanged |
TabIndex was settable |
TabIndex is read-only; use TabIndexChanged |
OnNavigatedTo() call required after construction |
the constructor selects the tab for the current url; the call is now optional |
OnNavigatedTo(string) could navigate |
it only resolves the tab; it never navigates |
Radzen.Blazor came in transitively |
add your own Radzen.Blazor PackageReference |