Challenge

Earlier today I had difficulty integrating with Facebook Open Graph and called their Open Graph Debugger for help. I also used Twitter Card Validator to verify if the page can be rendered as a Twitter card. There were still missing pieces from meta data. The complete Open Graph and Twitter card meta data would look like this:

<!-- Provide absolute URLs -->
<meta name="title" content="Page Title for Search Engines Results | Website Name" />
<meta name="description" content="Page Description for Search Engine Results" />
<meta property="og:title" content="Page Title for Facebook" />
<meta property="og:description" content="Page Description for Facebook" />
<meta property="og:image" content="https://www.sitename.com/image-for-facebook.png" />
<meta property="twitter:card" content="summary" />
<meta property="twitter:description" content="Page Description for Twitter." />
<meta property="twitter:title" content="Page Title for Twitter" />
<meta property="twitter:image" content="https://www.sitename.com/image-for-twitter.png" />

I’m using a theme called hugo-geo which does not have the following meta tags:

<meta name="title">
<meta property="og:image">
<meta property="twitter:card">
<meta property="twitter:description">
<meta property="twitter:title">
<meta property="twitter:image">

So now I want to populate those fields by overriding the partial theme layouts/partials/head.html.

Solution

There’s certainly lack of documentation on how to access page variables in Hugo but I found a piece that could help: Hugo Page Variables.

To populate <meta name="title"> is easy, we could reuse the variable .Title provided by all pages. Now the challenge is printing a custom image for <meta property="og:image"> and <meta property="twitter:image">. After digging and googling, I found 3 ways for accessing custom page variables (in this case thumbnail):

{{ if $.Page.Params.thumbnail }}
<meta property="og:image" content="{{ .Site.BaseURL }}{{ $.Page.Params.thumbnail }}">
{{ end }}

{{ if .Params.thumbnail }}
<meta property="og:image" content="{{ .Site.BaseURL }}{{ .Params.thumbnail }}">
{{ end }}

{{ if $.Params.thumbnail }}
<meta property="og:image" content="{{ .Site.BaseURL }}{{ $.Params.thumbnail }}">
{{ end }}

To make this work, remember to add a new variable thumbnail to your page’s front matter:

+++
thumbnail = "pimages/00005-good-twitter-card-validator.jpg"
+++
---
thumbnail = "pimages/00005-good-twitter-card-validator.jpg"
---

To see concrete implementation of the partial template head.html, check my gist. I created a pull request for hugo-neo and hope that the author will accept it: https://github.com/alexurquhart/hugo-geo/pull/27

Now Twitter and Facebook give us good validation results:

Validated Twitter Card

Facebook Post with Preview

If you want large image in the summary, simply add:

<meta name="twitter:card" content="summary_large_image">

Twitter Card: Summary Large Image

References