This website stores cookies on your computer. These cookies are used to collect information about how you interact with the website and allows us to remember you. We use this information in order to improve and customize your browsing experience and for analytics and metrics about visitors to this website. If you decline, your information won’t be tracked when you visit this website. A single cookie will be used in your browser to remember your preference not to be tracked.
Blog > SEO > Google's SEO Starter Guide Part III

Google's SEO Starter Guide Part III

We are back looking at the SEO documentation provided by Google.

Using ‘breadcrumb lists'

"Create a naturally flowing hierarchy"

Avoid requiring script or plugin-based event-handling for navigation.

This will make navigation from an article back to the initial navigation point very easy. I could use JavaScript to track if a visitor entered the page from the main Blog page, the Tag Word Cloud or via Date navigation. However the navigation being dynamically generated wouldn't indicate to the search engine where the page sits in the website hierarchy, although I think this would be nice, a better approach might be to have a 'primary' tag that could be used for navigation. This page for instance will have the breadcrumbs of Blog > SEO > Google's SEO Starter Guide Part III where the SEO breadcrumb will take the visitor to SEO tag page and the Blog back to the Blog page. For the time being this could sit in the layout.erb before the article is rendered, I can always move this later.

First thing is to add some new frontmatter. I will add a articlenavigationtag parameter, for this page you are on viewing now I will have:

---
blog: main
title: Google's SEO Starter Guide Part III
date: 2020-05-06
tags: Google, SEO, AWS CloudFront, Terraform
article_navigation_tag: SEO
description: |
  In this article we are back looking at Googles SEO starter guide.  I have added breadcrumbs that should help visitors and search engines to navigate the sight...
---

Next we need to amend the layout.erb to make use of the new frontmatter. In the layout.erb I already make use of the frontmatter parameter description to recognise that I am dealing with an article page as these are the only pages with a description. I can use this same logic to render the navigation breadcrumb. This section of the layout.erb will need an extra line and will change from:

...
<% if defined?(current_page.data.description) %>
  <main class="container text-light">
    <%= yield %>
  </main>
  <div class="container">
    <%= partial "partials/blog_nav" %>
  </div>

<% elsif defined?(current_page.data.archive) %>
<h1 class="display-4 my-3 my-sm-3 my-md-3 my-lg-3 text-center text-light"><%= current_page.date.strftime('%e %B %Y') %></h1>

<main class="container text-light">
  <%= yield %>
</main>

<% else %>

  <main>
    <%= yield %>
  </main>

<% end %>
...

to be

...
<% if defined?(current_page.data.description) %>
  <main class="container text-light">
    <% link_to('/blog.html') do %>Blog<% end %> > <%= "<a href=\"/blog/tags #{current_page.data.article_navigation_tag.downcase}.html\">#{current_page.data.article_navigation_tag.downcase.tr(" ", "-")}</a>" %> > <%= current_article.title %>
    <%= yield %>
  </main>
  <div class="container">
    <%= partial "partials/blog_nav" %>
  </div>

<% elsif defined?(current_page.data.archive) %>
<h1 class="display-4 my-3 my-sm-3 my-md-3 my-lg-3 text-center text-light"><%= current_page.date.strftime('%e %B %Y') %></h1>

<main class="container text-light">
  <%= yield %>
</main>

<% else %>

  <main>
    <%= yield %>
  </main>

<% end %>
...

The tag.html.erb will need the breadcrumb too in order for the navigation to make sense. Again it’s just one line change the start of the page, from:

---
blog: main
pageable: true
per_page: 12
---
<div class="container text-light">
  <h1 class="display-4 text-center my-3 my-sm-3 my-md-3 my-lg-3">Articles tagged with '<%= tagname %>'</h1>
...

to be

---
blog: main
pageable: true
per_page: 12
---
<div class="container text-light">
  <% link_to('/blog.html') do %>Blog<% end %> > <%= tagname %>
  <h1 class="display-4 text-center my-3 my-sm-3 my-md-3 my-lg-3">Articles tagged with '<%= tagname %>'</h1>
...

Now the annoying part. I will now need to go back through every article and add the new frontmatter parameter.

Create a navigation page for users, a sitemap for search engines

Avoid letting your navigational page become out of date with broken links. Avoid creating a navigation page that simply lists pages without organizing them, for example by subject.

I don’t think the site is too difficult to navigate as a human and a navigation page isn’t required.

I do however need to generate a new sitemap whenever I run a build. A quick google and I have found this Middleman extension that can be used to generate the sitemap. Following their documentation add gem 'middleman-sitemap-xml-generator' to the Gemfile and then on the command line run the bundle install command.

cd ~/middleman_project
bundle install

Amend the config.rb

...
set :url_root, 'https://awebsitefromscratch.com'
activate :search_engine_sitemap
...

In order for Google to be aware of the sitemap I also need to add a robots.txt in my source directory with the content:

Sitemap: https://awebsitefromscratch.com/sitemap.xml

Running a build now results in the files robots.txt and sitemap.xml being added to the build directory.

Once the sitemap.xml file has been deployed and I can navigate to it via https://awebsitefromscratch.com/sitemap.xml I can manually register the page with Google Search.

Show useful 404 pages

Adding an Error page is pretty simple. It's just another erb file that can be displayed under the main layout.erb and then changing the Terraform maintained AWS CloudFront distribution to point 404 and 403 errors towards it. If we use the AWS CloudFront distribution from the Terraform code in the SEO Starter Guide Part II article as the starting point then a small amendment should be all that is required.

The aws_cloudfront_distribution resource will now be:

resource "aws_cloudfront_distribution" "s3_distribution" {

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "primaryS3"

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
  }

  enabled = true

  origin {
    domain_name = var.s3_bucket_regional_domain_name
    origin_id   = "primaryS3"

    s3_origin_config {
      origin_access_identity = var.cloudfront_access_identity_path
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = false
    acm_certificate_arn            = aws_acm_certificate.cert.arn
    ssl_support_method             = "sni-only"
    minimum_protocol_version       = "TLSv1.1_2016"
  }

  aliases             = [
    element(var.domain_names, 0),
    element(var.domain_names, 1),
    "www.${element(var.domain_names, 0)}",
    "www.${element(var.domain_names, 1)}"
  ]
  default_root_object = "index.html"
  price_class         = "PriceClass_100"

  custom_error_response {
    error_code            = 404
    response_page_path    = "/error.html"
    error_caching_min_ttl = 3600
    response_code         = 200
  }

  custom_error_response {
    error_code            = 403
    response_page_path    = "/error.html"
    error_caching_min_ttl = 3600
    response_code         = 200
  }
}

Google's SEO starter guide continues from here but pertains more to the content and the audience of the site. In terms creating new and amending site resources this is as far as I can go.

Sites search performance

Time for another look at how the site is performing in terms of search.

Date Total Impressions Total Clicks Average Position Valid Pages Pages in Error Valid Mobile Pages Mobile Pages in Error
16 March 2020 1 0 174 31 0 2 0
25 March 2020 2 0 89.5 31 0 2 0
29 March 2020 3 0 60 31 0 2 0
11 April 2020 3 0 60 31 0 1 0
24 May 2020 40 0 23.9 82 0 2 0

The jump in the number of pages is due to now having https as opposed to http and despite the increase in impressions there has still yet to be any click throughs, I am still writing for myself. The highest the page the site has come up in someone's search is 5, so I am making progress but not there yet.