Hugo SEO / Social Partials

@bjornerik - I didn’t add the documentation mainly because the discussion never fleshed itself out, and there wasn’t a consensus on how/where to store the information. Last I heard @spf13 was adding support for some extra files, so we could standardize on putting everything in an authors.json|toml|yaml file. If that’s available and my structs are acceptable, then I’m more than happy to add some docs.

It is allowed to be proactive. If you come up with a good design, I’m sure you will get acceptance for it.

Additional data files are supported today in Hugo. @DerekPerkins. Please be proactive. I think the approach should be “here’s help if you want it, but you can go on the same way you are today and be fine”.

I like the idea of authors.json|toml|yaml and support for it in structs.

This is what I currently use in my head section of https://stoned.io

<!-- open graph -->
<meta property="og:title" content="{{ if ne .URL "/" }} {{ .Title }} - {{ end }} {{ .Site.Title }}" />
<meta property="og:description" content="{{ .Params.description }}" />
<meta property="og:site_name" content="{{ .Site.Title }}" />
<meta property="og:url" content="{{ .Permalink }}" />
<meta property="fb:app_id" content="{{ .Site.Params.fb_appid}}" />
<meta property="og:locale" content="{{ .Site.LanguageCode }}">

{{ if .IsPage }}
<!-- If it is part of a series, link to related articles -->
{{ $permalink := .Permalink }}
{{ $siteSeries := .Site.Taxonomies.series }}
{{ with .Params.series }}
{{ range $name := . }}
{{ $series := index $siteSeries $name }}
{{ range $page := first 6 $series.Pages }}
{{ if ne $page.Permalink $permalink }}
<meta property="og:see_also" content="{{ $page.Permalink }}" />
{{ end }}
{{ end }}
{{ end }}
{{ end }}
<meta property="og:type" content="article" />
<meta property="article:modified_time" content="{{ .Date }}" />
<meta property="article:section" content="{{ .Section }}" />
<meta property="article:published_time" content="{{ .Date.Format "2006-01-02T15:04:05Z07:00" | safeHTML }}" />
{{ with .Params.og_images }}{{ range first 6 . }}
<meta property="og:image" content="{{ . }}" />
{{ end }}{{ end }}
<meta property="og:image" content="{{ .Params.og_image }}" />
<meta property="og:image:url" content="{{ .Params.og_image }}" />
{{ range .Params.tags }}
<meta property="article:tag" content="{{ . }}" />
{{ end }}
{{ else }}
<meta property="og:type" content="blog" />
<meta property="og:image" content="{{ .Site.Params.og_image }}" />
<meta property="og:image:url" content="{{ .Site.Params.og_image }}" />
{{ end }}

<!-- twitter -->
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:image:src" content="{{ .Params.og_image }}"/>
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="{{ .Title }}"/>
<meta name="twitter:description" content="{{ if .Description }}{{ .Description }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ end }}{{ end }}"/>
<meta name="twitter:domain" content="{{ .Site.Title }}"/>
<meta name="twitter:creator" content="{{ .Site.Params.authortwitter }}"/>

Works off of the article front matter.

+++
categories = ["self-improvement"]
date = "2016-09-13T20:40:34-06:00"
tags = ["Self-improvement"]
title = "10 Small Steps To Improve Your Life - The Power of Gradual Change"
description = "How To Make 10 Small Common Improvements To Become A Better Person - The Power of Small Improvements and Marginal Gains"
og_image = "http://www.change-gear.com/wp-content/uploads/2015/05/Big-journeys.jpg"
og_image_url = "http://www.change-gear.com/wp-content/uploads/2015/05/Big-journeys.jpg"
google_news_keywords = ["10 small steps to improving your life", "Power of Gradual Change in 10 Steps"]
+++

Also, for the conditionals, the main site og data/images are defined in the project’s config.toml

fb_appid = "1103056659786546"
og_image = "https://stoned.io/images/og.image.png"
og_image_url = "https://stoned.io/images/og.image.png"
githubName = ""
twitterName =  "@HashBorgir"

<!-- set height/width to 0px so this schema.org info div doesn't screw up formatting -->
<div style="height: 0px; width: 0px;">
<!-- Add this code to article page: -->
<div itemscope itemtype='http://schema.org/Article'>
    <meta itemprop='inLanguage' content='{{ .Site.LanguageCode }}'/>
    <meta itemprop='about' content='{{ .Description }}' />
    <meta itemprop='isFamilyFriendly' content='False'/>
    <h1 itemprop='name headline'>{{ .Title }}</h1>

    <!-- Article image start: -->
    <div itemprop='associatedMedia'>
        <span itemscope itemtype='http://schema.org/ImageObject'>
            <img itemprop='contentURL' src='{{ .Params.og_image }}'/>
            <div>
            Credit: <span itemscope itemprop='author' itemtype='http://schema.org/Person'>
            <span itemprop='name'>{{ .Site.Params.twitterName}}</span>
        </span> /
                <span itemprop='sourceOrganization'>
                    <span itemscope itemtype='http://schema.org/Organization'>
                        <span itemprop='name'>{{ .Site.Title }}</span>
                    </span>
                </span>
            </div>
            <div itemprop='caption'>{{ .Site.Title }}</div>
        </span>
    </div>
    <!-- Article image end -->

    <!-- Authorship instructions start: -->
    Written by:
    <span itemscope itemprop='author' itemtype='http://schema.org/Person'>
        <span itemprop='name'>
            <a itemprop='url' href='{{ .Site.BaseURL }}'>{{ .Site.BaseURL }}</a>
        </span>
    </span>
    <!-- Authorship instructions end -->

    Published by:
    <span itemscope itemprop='sourceOrganization' itemtype='http://schema.org/Organization'>
        <span itemprop='name'><a itemprop='url' href='{{ .Site.BaseURL }}'>{{ .Site.Title }}</a></span>
        <img itemprop='logo' src='{{ .Site.BaseURL }}images/og.image.png' />
    </span>

    Copyright holder:
    <span itemscope itemprop='sourceOrganization' itemtype='http://schema.org/Organization'>
        <span itemprop='name'><a itemprop='url' href='{{ .Site.BaseURL }}'>{{ .Site.Title }}</a></span>
        <img itemprop='logo' src='{{ .Site.BaseURL }}images/og.image.png' />
    </span>
        on
    <time datetime='{{ .Date }}' itemprop='datePublished'>{{ .Date }}</time>
    {{ if .IsPage }}
    <div itemprop='articleBody'> {{ .Summary }} </div>
    {{ end }}
</div>
</div>

This is what I use for my blog posts/articles schema.org markup.

I like your approach very much. There is now a need to have optimized and various sized images, so og:image should be an array and I’ll modify my code to take from your example.

Excellent work, guys. Thank you so much!

I’ll open my theme, stoned.io on github. I currently use gitlab with private repos.

1 Like

Looks a bit more advanced than my current own home-brew solution …
Guess I will give it a try, thank you!

Pretty good job done here I think ^^ is there a plan to facilitate this kind of seo-friendly-head in Hugo via a variable for example ? I’m thinking of jekyll-seo-tag

This is pretty straightforward to create yourself, but there are some snippets out there too.

Yes, but then the maintenance of the template would not be centralized in Hugo, neither updated according to the evolution of better practices, etc.