Creating Better SEO URLs

Google treats every version of a link as a separate link when it crawls your page in search of links to index. A link that contains www. is distinct from one that does not. This also applies to URLs in lowercase and capital letters. Because ASP.Net can handle both capital and lowercase URLs, your website will still function, although optimizing it for search engines is not advised. Additionally, you should make sure that you aren’t using http:// and https:// to create duplicate urls. Google will distribute the SEO value between those two distinct URLs, per Google’s perception.

Step 1 – Find Your Global.Asax

This should be located in your main solution directory.

Step 2 – Change Or Add Applicaton_BeginRequest Function

We are going to add three sections of code inside the Application_BeginRequest that will convert all http:// URLs to https:// URLs, convert all non www URLs to www URLs and lowercase the entire URL that way we are truly only creating one URL to be indexed by all the major search engines. If you’re site is not SSL secured please skip the HTTPs section.

The benefit to putting all of this in the Application_BeginRequest is that even if somebody creates a link to your website externally, when that link is clicked on the URL will do a 301 redirect telling all systems that it’s a permanent redirect. Having it in the Application_BeginRquest will also catch any mistakes you make throughout your code with uppercase and lowercase urls.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected void Application_BeginRequest(object sender, EventArgs e)
        {
            if (!HttpContext.Current.Request.IsLocal && !HttpContext.Current.Request.Url.Host.StartsWith("www"))
            {
                var Builder = new UriBuilder(Request.Url);
                Builder.Host = "www." + Request.Url.Host;
                Response.RedirectPermanent(Builder.ToString(), true);
            }
            if (HttpContext.Current.Request.IsSecureConnection == false && HttpContext.Current.Request.IsLocal == false)
            {
                Response.RedirectPermanent("https://" + Request.ServerVariables["HTTP_HOST"] + HttpContext.Current.Request.RawUrl);
            }
            var url = Request.Url.ToString();
            if (Regex.IsMatch(url, @"[A-Z]") && Request.HttpMethod != "POST" && !url.Contains("Bundles"))
            {
                Response.Clear();
                Response.Status = "301 Moved Permanently";
                Response.StatusCode = (int)HttpStatusCode.MovedPermanently;
                Response.AddHeader("Location", url.ToLower());
                Response.End();
            }
        }

SEO Tags

For the general SEO health of your website, having the correct SEO tags for your meta description, meta keywords, meta title, and canonical is crucial. If you don’t have these tags, Google and Bing will decide what information about your website will be displayed to users in search results. Additionally, canonical URLs implicitly instruct search engines as to what the page’s URL ought to be. When using querystring arguments, which alter the URL but not always the page’s content, this is quite helpful.

Step 1 – Update Your _Layout.Cshtml To Create Dynamic Tags For The Following: Title, Meta Description, Meta Keywords And Canoncial.

In the <head></head> insert the following.

1
2
3
4
<title>@ViewBag.Title</title>
<meta name="description" content="@ViewBag.MetaDescription">
<meta name="keywords" content="@ViewBag.MetaKeywords">
<link rel="canonical" href="@ViewBag.CanonicalURL" />

This is an example from the top of my index.cshtml which renders our home page.

1
2
3
4
5
6
@{
    ViewBag.Title = "Mobilize Cloud - Columbus Web Development Agency";
    ViewBag.MetaDescription = "We are one of Columbus, Ohio's top web development agencies. With a focus on custom web applications, digital marketing, SEO/SEM and more we build solutions to solve your business problems. Our services include: Websites, Web Applications, E-Commerce, The Cloud, Social Media, Search Engine Optimization(SEO) and Digital Marketing. Columbus Web Development.";
    ViewBag.MetaKeywords = "Columbus Web Development, Mobilize Cloud, MobilizeCloud, Mobilize, Mobilize Web Development, Columbus Ohio Web, Columbus Ohio Web Development, Web Development Columbus, Web Development Ohio, Columbus Website, Ohio Website, TopCME, OSU CCME, Custom Web Development, Responsive Web Development, Columbus SEO, Columbus Search Engine Optimization";
    ViewBag.CanonicalURL = "https://www.domain.com";
}

Step 2 – Now You Can Add Dynamic ViewBag Properties In Each Of Your Views Or Controllers.

Step 3 – Dynamic Content

Instead of declaring these properties in your view you can assign them at the controller level stripping out keywords from content you may have stored in your model.

This example using a custom library we created call KeywordAnalyzer that can find the top keywords from body copy. We first strip any html tags so they are not included as keywords.

We are also incorporating the BlogPost.Title into the title of the page. We will post our KeywordAnalyzer library to github and provide a link soon.

1
2
3
4
var KeywordAnalyzer = new KeywordAnalyzer();
ViewBag.Title = BlogPost.Title + " | Mobilize Cloud - Columbus Web Development";
ViewBag.MetaKeywords = string.Join(", ", KeywordAnalyzer.Analyze(StringFunctions.StripHTML(BlogPost.Body)).Keywords.OrderBy(k => k.Rank).Select(k => k.Word));
ViewBag.MetaDescription = BlogPost.Summary;

Google Search Features

Rich cards, rich results, and other search options have all been heavily promoted by Google. Developers must utilize Microdata or JSON-LD markup to accomplish this. For novice developers who are unfamiliar with either of those markup formats, this may be confusing.

Google has done a really good job of explaining everything and providing example at the following site: Introduction to Structured Data Types. Below are several examples of the most common markups you can add to your site. They include breadcrumbs, organization data and blog/article information. There are a handful of additional features that we won’t go in depth into but more information on Recipes, Events, Products, Reviews and Courses can be found on Google’s Search Gallery.

If you need help with your specific scenario, feel free to leave us a comment below and we can help direct you in the right direction on which structure data types you should add to your site.

Setup

We often are setting structure data in our individual views throughout our site. In order to code them properly so they show up right above the closing </body> tag we have implement a @RenderSection for “Script” that is placed in our _Layout file for the site.

1
@RenderSection("Scripts", required: false)

The purpose of the required:false is to let the RenderSection call know that Scripts is not required in every view that we create. More information on the RenderSection call can be found in the MSDN documenation for System.Web.Webpages.

To then utilize the RenderSection throughout our code we can then simply use the following in each view:

1
2
@section Scripts{
//Place Code here}

Breadcrumbs.

Breadcrumbs are very beneficial to search engines because it helps them determine the hierarchy of your site and how pages are interconnected. When google structured data for breadcrumbs are used and indexed by google you can expect to see the following result on your search listings.

To accomplish this you can use JSON-LD markup or Microdata. Our prefeence is JSON-LD because it’s a much cleaner markup that can be place inside a RenderSection <script></script> tag versus being marked up directly in our HTML.

JSON-LD Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@section Scripts{
<script type="application/ld+json">
{
  "@@context""http://schema.org",
  "@@type""BreadcrumbList",
  "itemListElement": [{
    "@type""ListItem",
    "position": 1,
    "item": {
      "@@id""https://example.com/books",
      "name""Books",
      "image""http://example.com/images/icon-book.png"
    }
  },{
    "@@type""ListItem",
    "position": 2,
    "item": {
      "@@id""https://example.com/books/authors",
      "name""Authors",
      "image""http://example.com/images/icon-author.png"
    }
  },{
    "@@type""ListItem",
    "position": 3,
    "item": {
      "@@id""https://example.com/books/authors/annleckie",
      "name""Ann Leckie",
      "image""http://example.com/images/author-leckie-ann.png"
    }
  },{
    "@@type""ListItem",
    "position": 4,
    "item": {
      "@@id""https://example.com/books/authors/ancillaryjustice",
      "name""Ancillary Justice",
      "image""http://example.com/images/cover-ancillary-justice.png"
    }
  }]
}
}
</script>

Microdata Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<ol itemscope itemtype="http://schema.org/BreadcrumbList">
  <li itemprop="itemListElement" itemscope
      itemtype="http://schema.org/ListItem">
    <a itemscope itemtype="http://schema.org/Thing"
       itemprop="item" href="https://example.com/books">
        <span itemprop="name">Books</span>
        <img itemprop="image" src="http://example.com/images/icon-bookicon.png" alt="Books"/></a>
    <meta itemprop="position" content="1" />
  </li>
  
  <li itemprop="itemListElement" itemscope
      itemtype="http://schema.org/ListItem">
    <a itemscope itemtype="http://schema.org/Thing"
       itemprop="item" href="https://example.com/books/sciencefiction">
      <span itemprop="name">Science Fiction</span>
      <img itemprop="image" src="http://example.com/images/icon-science-fiction.png" alt="Genre: Science Fiction"/></a>
    <meta itemprop="position" content="2" />
  </li>
  
  <li itemprop="itemListElement" itemscope
      itemtype="http://schema.org/ListItem">
    <a itemscope itemtype="http://schema.org/Thing"
       itemprop="item" href="https://example.com/books/sciencefiction/ancillaryjustice">
      <span itemprop="name">Ancillary Justice</span>
      <img itemprop="image" src="http://example.com/images/cover-ancillary-justice.png" alt="Ancillary Justice"/></a>
    <meta itemprop="position" content="3" />
  </li>
</ol>

For more examples check out Google’s Breadcrumbs.

Organization Data

Organization data allows you to add things such as a company logo, corporate contact numbers, social profiles and more.

JSON-LD Example:

1
2
3
4
5
6
7
8
9
10
11
@section Scripts{
<script type="application/ld+json">
{
  "@@context""http://schema.org",
  "@@type""WebSite",
  "name""Your WebSite Name",
  "alternateName""An alternative name for your WebSite",
  "url""http://www.your-site.com"
}
}
</script>

Microdata Example:

1
2
3
<head itemscope itemtype="http://schema.org/WebSite">
<title itemprop='name'>Your WebSite Name</title>
<link rel="canonical" href="https://example.com/" itemprop="url">

Additional examples for Site Logos, Social Profile Links and Corporate

Blog/Article Information

Promoting your created content should be your number one priority. If you are going to invest the time to create quality blog posts and articles you should be sending as much data as possible to google to try and become their top listing for your topic. To do that we utilize Google’s structured data for Articles.

JSON-LD Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@section Scripts{
<script type="application/ld+json">
{
  "@@context""http://schema.org",
  "@@type""NewsArticle",
  "mainEntityOfPage": {
    "@@type""WebPage",
    "@@id""https://google.com/article"
  },
  "headline""Article headline",
  "image": {
    "@@type""ImageObject",
    "url""https://google.com/thumbnail1.jpg",
    "height": 800,
    "width": 800
  },
  "datePublished""2015-02-05T08:00:00+08:00",
  "dateModified""2015-02-05T09:20:00+08:00",
  "author": {
    "@@type""Person",
    "name""John Doe"
  },
   "publisher": {
    "@@type""Organization",
    "name""Google",
    "logo": {
      "@@type""ImageObject",
      "url""https://google.com/logo.jpg",
      "width": 600,
      "height": 60
    }
  },
  "description""A most wonderful article"
}
</script>

Microdata Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div itemscope itemtype="http://schema.org/NewsArticle">
  <meta itemscope itemprop="mainEntityOfPage"  itemType="https://schema.org/WebPage" itemid="https://google.com/article"/>
  <h2 itemprop="headline">Article headline</h2>
  <h3 itemprop="author" itemscope itemtype="https://schema.org/Person">
    By <span itemprop="name">John Doe</span>
  </h3>
  <span itemprop="description">A most wonderful article</span>
  <div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
    <img src="https://google.com/thumbnail1.jpg"/>
    <meta itemprop="url" content="https://google.com/thumbnail1.jpg">
    <meta itemprop="width" content="800">
    <meta itemprop="height" content="800">
  </div>
  <div itemprop="publisher" itemscope itemtype="https://schema.org/Organization">
    <div itemprop="logo" itemscope itemtype="https://schema.org/ImageObject">
      <img src="https://google.com/logo.jpg"/>
      <meta itemprop="url" content="https://google.com/logo.jpg">
      <meta itemprop="width" content="600">
      <meta itemprop="height" content="60">
    </div>
    <meta itemprop="name" content="Google">
  </div>
  <meta itemprop="datePublished" content="2015-02-05T08:00:00+08:00"/>
  <meta itemprop="dateModified" content="2015-02-05T09:20:00+08:00"/>
</div>
Rate this post