Home Articles Contact Us Client Area Register Login

Rel=Canonical: An Elegant Approach To Using the Canonical Tags in Razor Pages and MVC

Mark Pringle - Thursday, December 01, 2022

I love the Model-View-Controller architectural pattern. How ASP.NET Core MVC is structured provides web developers an elegant way to set canonical tags in Razor Pages. If you have a better approach, please let me know. My approach was as follows.

1) Place Head Components and Meta Data in a View Import

Instead of placing the head components in the _Layout page, I separated those head components into a _Head view import which I would import into the _Layout page.

I will use ViewData to determine whether or not to render the canonical tag. The way the code below is written, the canonical tag will not display unless  ViewData["Canonical"] is given a value on the Razor Page.

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"]</title>
<meta name="description" content="@ViewData["MetaDescription"]">
<meta property="og:image" content="@ViewData["ogimage"]" />
@if (ViewData["Canonical"] != null)
{
<link rel="canonical" href="@ViewData["Canonical"]" />
}
<!-- Font Awesome icons (free version)-->
<script src="https://use.fontawesome.com/releases/v6.1.0/js/all.js" crossorigin="anonymous"></script>
<!-- Google fonts-->
<link href="https://fonts.googleapis.com/css?family=Catamaran:100,200,300,400,500,600,700,800,900" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Lato:100,100i,300,300i,400,400i,700,700i,900,900i" rel="stylesheet" />
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />

2) Give  ViewData["Canonical"] a Value on the Razor Page (bottom of the code below).

@{
    @if (Model == null)
    {
        ViewData["Title"] = ViewData["Heading1"] = ViewData["MetaDescription"] = "Search";
    }
    else if (Model.Count() == 0)
    {
        ViewData["Title"] = ViewData["Heading1"] = ViewData["MetaDescription"] = "Search Results for " + @Context.Request.Query["id"];
    }
    else
    {
        ViewData["Title"] = ViewData["Heading1"] = ViewData["MetaDescription"] = "Search Results for " + @Context.Request.Query["id"];
    }

    ViewData["ogimage"] = "https://www.learnaspnet.com/images/default.jpg";
    ViewData["Canonical"] = "https://www.learnaspnet.com/searchresults";
}

That's it! If we had not given ViewData["Canonical"] a value, the canonical tag would not have been displayed as seen in the HTML source below.

<title>Search Results for Microsoft SQL Server</title>
<meta name="description" content="Search Results for Microsoft SQL Server">
<meta property="og:image" content="https://www.learnaspnet.com/images/default.jpg" />
<link rel="canonical" href="https://www.learnaspnet.com/searchresults" />
<!-- Font Awesome icons (free version)-->
<script src="https://use.fontawesome.com/releases/v6.1.0/js/all.js" crossorigin="anonymous"></script>
<!-- Google fonts-->

If you build pages properly, a canonical tag may not be necessary on certain pages. Ideally, you would like the page to produce an error if the URL is not what you intended.  However, we added one to our search results page so that search engines know not to index each query string URL.