static void

Blazor Navigation

Routing

NavigationManager

You can navigate with normal HTML anchors, NavLink (an anchor which matches the current url and sets the class active) and hook up to Navigation Manager

<ul>
    <li><a href="/counter">Go to counter page</a></li>
    <li><NavLink href="/counter">Go to counter page</NavLink></li>
    <li><button @onclick="ClickBtn">Go to counter page</button></li>
</ul>
@code {
    [Inject]
    public required NavigationManager NavigationManager { getset; }

    public void ClickBtn()
    {
        NavigationManager.NavigateTo("/counter");
    }

Navigating

Just add a spinner or text to the router in a <Navigating> element.

<Router AppAssembly="@typeof(Program).Assembly" >
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <Navigating>
        <p>Loading&hellip;</p>
    </Navigating>
</Router>

NavigationLock

You can subscribe to navigation events from the NavigationManager.

<NavigationLock can intercept external redirects (actually via window.beforeunload- no real control) and internal navigation. Note internal redirects are only within the page (not menu navigation - you need a NavigationLock in your NavMenu for that).

<NavigationLock ConfirmExternalNavigation="true"
                OnBeforeInternalNavigation="OnBeforeInternalNavigation" />

<EditForm OnSubmit="Save" EditContext="_editContext">
    <p><InputNumber @bind-Value="_model.Count"/></p>
    <button type="submit" disabled="@_formInvalid">Submit</button>
</EditForm>
<p>Is _editContext modified? @_editContext.IsModified()</p>

@code {
    private EditContext _editContext = default!;
    private bool _formInvalid = true;
    private CounterModel _model = default!;

    protected override void OnInitialized()
    {
        _model = new CounterModel();
        _editContext = new(_model);
        _editContext.OnFieldChanged += (___) =>
        {
            _formInvalid = !_editContext.Validate();
            StateHasChanged();
        };
    }

    [Inject]
    public IJSRuntime JsRuntime { getset; }

    private async Task OnBeforeInternalNavigation(LocationChangingContext locationChangingContext)
    {
        if (_editContext.IsModified())
        {
            //or a modal blazor component
            bool isConfirmed = 
                await JsRuntime.InvokeAsync<bool>("confirm""Leave without saving?");
            if (!isConfirmed)
            {
                locationChangingContext.PreventNavigation();
            }
        }
    }