How to create a dynamic breadcrumb navigation for .net core razor pages?

Viewed 10392

Im trying to create a breadcrumb navigation, i.e.

Home > Contact

I have found this answer - link

But it seams to be for MVC rather than razor pages. And i cant seam to find anything that works with razor pages.

Thanks in advance :)

Answer

As my answer was deleted by a moderator, here was my soloution -

To solve this I found this project - https://github.com/zHaytam/SmartBreadcrumbs

Very easy to use and worked flawlessly

3 Answers

I had this problem and solved it in this way:

At first I made a razor component for Breadcrumb like below:

 <nav aria-label="breadcrumb" style="background-color: #f2f2f3">
    <div class="mt-max-size">
        <ol class="breadcrumb">
            @foreach (var link in Links.OrderBy(x => x.OrderIndex))
            {
                if (link.IsActive)
                {
                    <li class="breadcrumb-item active mt-bread-item" aria-current="page">@link.Title</li>
                }
                else
                {
                    <li class="breadcrumb-item"><a class="mt-bread-item-link" href="@link.Address">@link.Title</a></li>
                }
            }
        </ol>
    </div>
</nav>
    @code{
        [Parameter]
        public List<Model.BreadcrumbLink> Links { get; set; }
        public Breadcrumb()
        {
    
        }
            protected override Task OnParametersSetAsync() => base.OnParametersSetAsync();
    }

And then I have used this component in my razor layout like below:

@inherits LayoutComponentBase
@inject NavigationManager NavigationManager

<Breadcrumb Links="@breadcrumbLinks" />

@code{
    private string currentUrl;
protected override void OnParametersSet() {
        breadcrumbLinks = new List<Model.BreadcrumbLink>();
        currentUrl = NavigationManager.Uri;
        var myUrl = currentUrl.Replace(NavigationManager.BaseUri, "");
        breadcrumbLinks.Add(new Model.BreadcrumbLink
        {
            Address = NavigationManager.BaseUri,
            IsActive = NavigationManager.Uri == NavigationManager.BaseUri,
            OrderIndex = 1,
            Title = @Localizer["Home".ToLower()]
        });
        var path = myUrl.Split('/');
        var count = 1;
        
        foreach (var link in path)
        {
            if (link == "") continue;
            count++;
            var lastLink = breadcrumbLinks.Last();
            breadcrumbLinks.Add(new Model.BreadcrumbLink
            {
                Address = $"{lastLink.Address}/{link}",
                IsActive = link == path.Last(),
                OrderIndex = count,
                Title = link
            });
        }
        base.OnParametersSet();
    }
}

Note: To pass the data I Have created a model: Model.BreadcrumbLink. You can see its definition below :

public class BreadcrumbLink
    {
        public int OrderIndex { get; set; }
        public string Address { get; set; }
        public string Title { get; set; }
        public bool IsActive { get; set; }
    }

I hope it be helpful !!

Since Razor Pages routing is based on the file structure in the Pages folder, you could just use that as the basis of generating breadcrumbs. Or you could use Context.Request.Path and split on the / to obtain the segments of the navigation. This could be very simple if you have a default (Index) document in every folder within the Pages folder. Otherwise you will have to check to see if files exist before rendering each crumb.

To solve this I found this project - https://github.com/zHaytam/SmartBreadcrumbs

  1. Simply install the NuGet package Install-Package SmartBreadcrumbs
  2. Initialize it in the startup services.AddBreadcrumbs(GetType().Assembly);
  3. In _ViewImports.cshtml, add @addTagHelper *, SmartBreadcrumbs
  4. In your _Layout.cshml (or specific pages), use <breadcrumb></breadcrumb>.
  5. On your default/ home page, add this annotation to the class [DefaultBreadcrumb("Home")]
  6. And on other pages add this to the class [Breadcrumb("Bookings")]
  7. Add if you want to link to a prevouse page add this to the class [Breadcrumb("Details", FromPage = typeof(IndexModel))]

Then if you want to customize the look of it simply update the start by adding the CSS classes you want to use -

services.AddBreadcrumbs(GetType().Assembly, options =>
{
    options.TagName = "nav";
    options.TagClasses = "";
    options.OlClasses = "breadcrumb";
    options.LiClasses = "breadcrumb-item";
    options.ActiveLiClasses = "breadcrumb-item active";
    options.SeparatorElement = "<li class=\"separator\">/</li>";
});
Related