image of the blog
ShadowThink Logo

SEO in Jekyll

Make your Jekyll blog a Google friendly site


This blog site has been online for almost two years. But it still gets very poor performance for search engine. When I search “shadowthink” in Google, I got quite wired result. The category page ranks higher than the home page! When I search “” in Google, my site gets #1 ranking as expected. But Google can’t catch important things as I wish. The result before SEO like this:

Search result before SEO

SEO Basics

Many blogs and some search engine already provide the guide for SEO. Here, I just summary some important tips for SEO and my personal suggestions for blog sites.

  • Title tag: your title tag should contains 10 and 70 characters without stop words. Be sure that each page has a unique title tag.

  • Meta description: Ideally, your meta description should contain between 70 and 160 charaters (spaces included). Ensure it unique and contains your most important keywords for each page.

Luckily, with Jekyll theme and Font Matter, we can easily match above two format requirements. Another useful tip is to build your keyword list. I use Google Keyword Planner to help me find relative and hot keywords. For example, if you want to add “machine learning” to Meta keyword, as the keyword tool suggests, you should also add “ml”, “machine learning algorithm” together with “machine learning”.

Improving Site Structure

In Jekyll, we can use permalink and sitemap to improve site structure.

  • Improve the structure of your URLs. My URLs configure: _config.yml
# config for posts
permalink: /blog/:categories/:year/:month/:day/:title


# config for collections
    output: true
    title: "Machine Learning"
    permalink: /pub/ml/:path
  • Sitemap: Jekyll documentation provides a generic use sitemap.xml. After check it in practice, I found the official version has a potential bug. If the page doesn’t contatin permalink in its FrontMatter, which usually occurs when you use jekyll paginate, it would generate null <loc> tag in sitemap. Fixing this is quite simple, please check my sitemap.xml

Be careful! Changing your website structure would generate many removal pages in Google search cache. Then we can use Google Search Console remove outdated content to remove them in Google cache.

Optimizing Content

Here, we wouldn’t talk about the post itself. I plan to investigate wordpress Yoast SEO in content optimizing perspective and develop new tool for jekyll. If you have any suggestions, please comment on this post.

Dealing with Crawlers

Because my website doesn’t have any sensitive stuff, so my robots.txt looks like this


User-agent: *
Allow: /

Promotions and Analysis

I use Google Search Console and Google Analysis for this site. Honestly, they are not so useful. Because SEO is long time process, after you modified settings in Search Console, you cannot retrieve the new results immediately. Sometimes, I follow Google instructions trying to display sub menu in the search results. After several days, recheck it, and may find, “IT DOESN’T WORK AT ALL!”. I believe the main reason is that your website doesn’t have high natural search traffic, and your settings are probably somewhat put off by Google.

Anyway, there are still something that meaningful for you to optimize your site based on these tools. Time will tell it helps a lot.

  • Twitter card: copy fellow Cards Markup into your <head> generator. With Twitter Cards, you can attach rich photos, videos and media experience to Tweets that drive traffic to your website.
{% if site.owner.twitter %}<!-- Twitter Cards -->
{% if page.imagefeature %}<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="{{ site.url }}/images/{{ page.imagefeature }}">
{% else %}<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="{% if page.image.thumb %}{{ site.url }}/images/{{ page.image.thumb }}{% else %}{{ site.url }}/images/{{ site.logo }}{% endif %}">{% endif %}
  • Facebook open graph: copy fellow open graph markup into your <head> generator.
<!-- Open Graph -->
<meta property="og:locale" content="en_US">
<meta property="og:type" content="article">
<meta property="og:title" content="{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}">
<meta property="og:description" content="{% if page.description %}{{ page.description }}{% else %}{{ site.description }}{% endif %}">
<meta property="og:url" content="{{ site.url }}{{ page.url }}">
<meta property="og:site_name" content="{{ site.title }}">
{% if page.imagefeature %}<meta property="og:image" content="{{ site.url }}/images/{{ page.imagefeature }}">{% else %}<meta property="og:image" content="{{ site.url }}/images/{{ site.default_bg }}">{% endif %}
  • Google structured data: structured data markup is a standard way to annotate your content so machines can understand it. It’s a signal for search engine to build corresponding knowledge graph. provides the standards in details. But it’s hard to do manual check on webpage. Luickly, Google offers a versatile tool, Structured Data Testing Tool. You can use it to fix errors easily.

Google Structured Data Testing Tool use case


After doing all of this, you should update and keep going. With the increment of natural traffic, the more efficient effect it will be.