120

I need to know the URL of the current page in order to check if I have to apply a certain style to an element. The code below is an example.

    @using Microsoft.AspNetCore.Blazor.Services
    @inject IUriHelper UriHelper
    @implements IDisposable

    <h1>@url</h1>
    <nav>
        <div class="nav-wrapper">
            <a href="#" class="brand-logo">Blazor</a>
            <ul id="nav-mobile" class="right hide-on-med-and-down">
                <li>
                    <NavLink href="/" Match=NavLinkMatch.All>
                        Home
                    </NavLink>
                </li>
                <li>
                    <NavLink href="/counter">
                        Counter
                    </NavLink>
                </li>
                <li>
                    <NavLink href="/fetchdata">
                        Fetch data
                    </NavLink>
                </li>
            </ul>
        </div>
    </nav>

    @functions {

        private string url = string.Empty;

        protected override void OnInit()
        {
            url = UriHelper.GetAbsoluteUri();
            UriHelper.OnLocationChanged += OnLocationChanged;
        }

        private void OnLocationChanged(object sender, LocationChangedEventArgs e)
        {
            url = newUriAbsolute;
        }

        public void Dispose()
        {
            UriHelper.OnLocationChanged -= OnLocationChanged;
        }
    }

I used the same approach used in the NavLink component in the Blazor repository, but it did not work. Any ideas?.

1
  • GetAbsoluteUri() works for me, what exactly is the problem? Commented Apr 30, 2018 at 15:45

6 Answers 6

263

Use the Uri property from the NavigationManager class.

How it works

Get it from injection before using it on .razor pages:

@inject NavigationManager MyNavigationManager

Or like this in a .cs file if you prefer the "code-behind" experience:

using Microsoft.AspNetCore.Components;
// ...
[Inject]
public NavigationManager MyNavigationManager {get; set;} = default!;

Sample

@page "/navigate"
@inject NavigationManager MyNavigationManager

<h1>Current URL</h1>

<p>@(MyNavigationManager.Uri)</p>

More about navigation (NavigateTo, BaseUri, ToAbsoluteUri, ToBaseRelativePath, ... ) at: URI and navigation state helpers

NavigationManager cheatsheet

MyNavigationManager.Uri
#> https://localhost:5001/counter/3?q=hi

MyNavigationManager.BaseUri
#> https://localhost:5001/

MyNavigationManager.NavigateTo("http://new location")
#> Navigates to new location

MyNavigationManager.LocationChanged
#> An event that fires when the navigation location has changed.

MyNavigationManager.ToAbsoluteUri("pepe")
#> https://localhost:5001/pepe

MyNavigationManager.ToBaseRelativePath(MyNavigationManager.Uri)
#> counter/3?q=hi

// Create a new URI based on the current address
// with the specified query string parameter added or updated.
NavigationManager.GetUriWithQueryParameter("page", 3)
#> https://localhost:5001/counter/3?q=hi&page=3

Helper: GetQueryParm( "q" )
#> hi

(*1) Net6 introduces GetUriWithQueryParameter. More info: Manipulate the query string from Blazor

Helpers code:

@code {

    [Parameter]
    public string Id { get; set; }


    // Blazor: get query parm from the URL
    string GetQueryParm(string parmName)
    {
        var uriBuilder = new UriBuilder(MyNavigationManager.Uri);
        var q = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query);
        return q[parmName] ?? "";
    }

}
Sign up to request clarification or add additional context in comments.

6 Comments

starting with v0.8.0 when using server side mode you should use: @inject Microsoft.AspNetCore.Components.Services.IUriHelper UriHelper and when using client-side mode: @inject Microsoft.AspNetCore.Blazor.Services.WebAssemblyUriHelper UriHelper
@ Henry Rodriguez, no, you're wrong. The correct way is to inject IUriHelper, not the implementation..
It's not working if usert try to force to another page over the Url address
The cheatsheet is very helpful +1
Cheatsheet GetQueryParam only works with query parameters, how would you get route parameters?
|
15

First of all, inject NavigationManager into the component in which you need to get the current URL as below:

@inject NavigationManager NavManager

Now use the below line to get the current URL:

string Url = NavManager.Uri.ToString();

Comments

4

There is no use in connecting to the OnLocationChanged event in a page or component, as they get loaded and disposed on demand.

You should register to this event in app.cshtml as that won't be disposed.

Comments

4

In my case I only needed the Uri of the page and not the base Uri aswell.

I keep all my code in a razor.cs file so I inject NavigationManager from code-behind like this:

[Inject] public NavigationManager Navigation { get; set; } 

Navigation.Uri yeilds: https://localhost:5001/nail-square-singel-shear-timber-timber

So to get the page Uri just do like this:

Navigation.Uri.Replace(Navigation.BaseUri,"")

The above yields: nail-square-singel-shear-timber-timber

1 Comment

This is the purpose of the method NavigationManager.ToBaseRelativePath(string uri).
3

You should listen to a LocationChange of the IUriHelper, which triggers the function to do what you want for example:

@using Microsoft.AspNetCore.Blazor.Components
@using Microsoft.Extensions.Logging
@inject Microsoft.AspNetCore.Blazor.Services.IUriHelper UriHelper
@inject ILogger<NavItem> logger

<li class="m-menu__item @(Active ? "m-menu__item--active" : "")">
    <a href=@Url class="m-menu__link ">
        <span class="m-menu__item-here"></span>
        <i class="m-menu__link-icon @Icon"></i>
        <span class="m-menu__link-text">@Text</span>
    </a>
</li>

@functions {
    protected override void OnInit()
    {
        UriHelper.OnLocationChanged += OnLocationChanges;
    }
    [Parameter]
    private string Url { get; set; }
    [Parameter]
    private string Icon { get; set; }
    [Parameter]
    private string Text { get; set; }
    private bool Active = false;
    private void OnLocationChanges(object sender, string newLocation)
    {
        bool active = newLocation.Contains(Url);
        if(active != Active) //Only re-render the components that need it
        {
            Active = active;
            StateHasChanged();
            logger.LogInformation("Location Change To:" + newLocation);
        }
    }
}

2 Comments

This UriHelper.OnLocationChanged event has new parameters that were causing an error with this example with .netCore 3 preview6. Should be: private void OnLocationChanges(object sender, LocationChangedEventArgs e)
this answer was for an out-dated version of blazor, use NavigationManager now.
3

Create somewhere an extension method like this:

namespace YourSolution.YourProject
{
    public static class NavigationManagerExtention
    {
        public static string Page(this NavigationManager navigation)
        {
            return navigation.Uri.Substring(navigation.BaseUri.Length - 1);
        }
    }
}

and to get the page part of URL just call _nav.Page()

Examples:

  • For example.com/home it returns /home
  • For example.com/ it returns /

If you don't need a slash char (/) replace

return navigation.Uri.Substring(navigation.BaseUri.Length - 1);

with

return navigation.Uri.Substring(navigation.BaseUri.Length);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.