Anchor
Anchor

Creating Anchor Links in Blazor Applications

A while ago, I wrote about Blazor Bootstrap , which is a Razor component library for Blazor applications that want to use Bootstrap as UI framework.

The other day, I was working on the Heading component, and wanted to make it possible to turn every Heading into an anchor link. This would allow you to easily link directly to each heading on the page. Here is quite a descriptive explanation of what an anchor link is.

An anchor link is a web link that allows users to leapfrog to a specific point on a website page. It saves them the need to scroll and skim read – and makes navigation easier.

Doesn’t sound too hard, does it? Just add an <a> element to the heading, and specify a unique ID as href , as shown below.


            
<h2 id="the-heading"><a href="#the-heading">The Heading</a></h2>

            

So it turns out that it unfortunately is not quite that easy. To make it easier for you to follow, I created a repository on GitHub with the solution to the problems described below. The sample application in the repository is also published on GitHub Pages at https://mikaberglund.github.io/anchor-link-in-blazor-application/

Problem

The problem with anchor links is that when you click on them, the page won’t scroll to the element you’ve specified in the link. Anchor links will always take you to the top of the front page of your application. This has to do with how routing is handled in Blazor and most other SPA applications as well. It’s definitely not just a problem with Blazor.

Luckily there is quite a simple solution. You just need to create your own AnchorLink component (or name it however you like) and use a little bit of JavaScript interop magic.

The AnchorLink component is built up of the AnchorLink.razor and the anchorLink.js files. The main responsibility of the Razor component is to examine the value of the href attribute and determine whether it is an anchor link. Anchor links starts with a hash ( # ). If it is an anchor link, then the default click action is prevented, and the scrollIntoView JavaScript function is called when the anchor is clicked using the injected JavaScript interop runtime.

The scrollIntoView JavaScript function supports the Razor component by scrolling the given element into view when the function is called.

When you have completed the AnchorLink component, you can use it in your application as a replacement for the default <a> element. Remember also to add a reference to the anchorLink.js file to the index.html template, so that the browser loads that file too.

You can use any standard attributes on the AnchorLink component as you would on an <a> element. Below are a few samples.


            
<p>

            
    The Table of Contents below demonstrate how

            
    you can use the <code>AnchorLink</code> component.

            
    You can also use it as a <AnchorLink href="...">normal link</AnchorLink>

            
    to point to any URI.

            
</p>

            
<ul>

            
    <li><AnchorLink href="#chapter1">Chapter 1</AnchorLink></li>

            
    <li><AnchorLink href="#chapter2">Chapter 2</AnchorLink></li>

            
    <li><AnchorLink href="#chapter3">Chapter 3</AnchorLink></li>

            
</ul>

            
<h2 id="chapter1">Chapter #1</h2>

            
<p>

            
    This is chapter #1.

            
</p>

            
<h2 id="chapter2">Chapter #2</h2>

            
<p>

            
    This is chapter #2.

            
</p>

            
<h2 id="chapter3">Chapter #3</h2>

            
<p>

            
    This is chapter #3. The source code to the <code>AnchorLink</code>

            
    component is available on <AnchorLink href="https://github.com/MikaBerglund/anchor-link-in-blazor-application" target="_blank">GitHub</AnchorLink>.

            
</p>

            

Conclusion

If you want to learn more about building components for your Blazor applications, I suggest you have a look at the Create and use AS.NET Core Razor components article. That will give you a very good overview of what’s possible.

And thanks to Chris Sainty , who pointed out some errors in this article, which I’ve now fixed.

An unhandled error has occurred. Reload 🗙