Academic Theme: Unable to Get Page/Post Featured Images on Twitter Card

I have been having difficulty getting Twitter Cards to work for my posts featured images. I have tried reviewing the twitter card code in the academic header and also by following the Hugo documentation. I am unsure if its something that missing or overlooking, any help or advice would be greatly appreciated.

I found this code in the academic header.html partial, yet I am still unsure as to why it is not working:


  {{ $featured_image := (.Resources.ByType "image").GetMatch "*featured*" }}
  {{ $og_image := "" }}
  {{ $twitter_card := "summary_large_image" }}
  {{ if $featured_image }}
    {{ $og_image = $featured_image.Permalink }}
  {{ else if .Params.header.image }}
    {{ $og_image = printf "img/%s" .Params.header.image | absURL }}
  {{ else if .Site.Params.sharing_image }}
    {{ $og_image = printf "img/%s" .Site.Params.sharing_image | absURL }}
  {{ else if .Site.Params.avatar }}
    {{ $og_image = (printf "img/%s" site.Params.avatar) | absURL }}
    {{ $twitter_card = "summary" }}
  {{ else }}
    {{ $og_image = "img/icon-192.png" | absURL }}
    {{ $twitter_card = "summary" }}
  {{ end }}
  <meta property="twitter:card" content="{{ $twitter_card }}">
  {{ with .Site.Params.twitter }}
  <meta property="twitter:site" content="@{{ . }}">
  <meta property="twitter:creator" content="@{{ . }}">
  {{ end }}
  <meta property="og:site_name" content="{{ .Site.Title }}">
  <meta property="og:url" content="{{ .Permalink }}">
  <meta property="og:title" content="{{ if not .IsHome }}{{ .Title }} | {{ end }}{{ .Site.Title }}">
  <meta property="og:description" content="{{ $desc }}">
  {{- with $og_image }}<meta property="og:image" content="{{ . }}">{{end}}
  <meta property="og:locale" content="{{ .Site.LanguageCode | default "en-us" }}">
  {{ if .IsPage }}
  {{ if not .PublishDate.IsZero }}<meta property="article:published_time" content="{{ .PublishDate.Format "2006-01-02T15:04:05-07:00" | safeHTML }}">
  {{ else if not .Date.IsZero }}<meta property="article:published_time" content="{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}">{{ end }}
  {{ if not .Lastmod.IsZero }}<meta property="article:modified_time" content="{{ .Lastmod.Format "2006-01-02T15:04:05-07:00" | safeHTML }}">{{ end }}
  {{ else }}
  {{ if not .Date.IsZero }}<meta property="og:updated_time" content="{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}">{{ end }}
  {{ end }}

Screenshot Card Validator Log
GitHub Repo

I think twitter uses twitter:image meta property.
I’m not sure why the academic theme does not use it, but you can try adding it to the header

Hi @madispe, thank you for the tip! I have tried adding the twitter:image tag to header.html partial shown below, although it does not seem to be working or maybe I have made an error?. Do I need to add anything to individual page frontmatter?

              {{ $og_image := "" }}
              {{ $twitter_card := "summary_large_image" }}
              {{ if $featured_image }}
                {{ $og_image = $featured_image.Permalink }}
              {{ else if .Params.header.image }}
                {{ $og_image = printf "img/%s" .Params.header.image | absURL }}
              {{ else if .Site.Params.sharing_image }}
                {{ $og_image = printf "img/%s" .Site.Params.sharing_image | absURL }}
              {{ else if .Site.Params.avatar }}
                {{ $og_image = (printf "img/%s" site.Params.avatar) | absURL }}
                {{ $twitter_card = "summary" }}
              {{ else }}
                {{ $og_image = "/img/icon-192.png" | absURL }}
                {{ $twitter_card = "summary" }}
              {{ end }}
              <meta property="twitter:card" content="{{ $twitter_card }}">
              {{ with .Site.Params.twitter }}
              <meta property="twitter:site" content="@{{ . }}">
              <meta property="twitter:creator" content="@{{ . }}">
              <meta name="twitter:image" content="@{{ . }}">
              {{ end }}
              <meta property="og:site_name" content="{{ .Site.Title }}">
              <meta property="og:url" content="{{ .Permalink }}">
              <meta property="og:title" content="{{ if not .IsHome }}{{ .Title }} | {{ end }}{{ .Site.Title }}">
             ``` <meta property="og:description" content="{{ $desc }}">
              {{- with $og_image }}<meta property="og:image" content="{{ . }}">{{end}} 

Card Validator Screenshot

Yes you made an error. You have an extra @ there and the content is set to your twitter handle (from site.Params.twitter instead of the image.
If you want the twitter image to be the same as the one in og:image, just add

{{ with $og_image }}<meta property="twitter:image" content="{{ . }}">{{ end }}

below the twitter:card property.

1 Like

Hi, @madispe thank you for your time, appreciate it. So I added removed the additional ‘@’ characters from the section. Then I added the code snippet you supplied {{ with $og_image }}<meta property="twitter:image" content="{{ . }}"> {{ end }} I had to remove the {{ end }} tag on that snippet as it was causing a build error. So this left me with the following code, unfortunately, the card validator is showing the same results, which is leaving me a little confused :confused:

{{ $featured_image := (.Resources.ByType "image").GetMatch "*featured*" }}
  {{ $og_image := "" }}
  {{ $twitter_card := "summary_large_image" }}
  {{ if $featured_image }}
    {{ $og_image = $featured_image.Permalink }}
  {{ else if .Params.header.image }}
    {{ $og_image = printf "img/%s" .Params.header.image | absURL }}
  {{ else if .Site.Params.sharing_image }}
    {{ $og_image = printf "img/%s" .Site.Params.sharing_image | absURL }}
  {{ else if .Site.Params.avatar }}
    {{ $og_image = (printf "img/%s" site.Params.avatar) | absURL }}
    {{ $twitter_card = "summary" }}
  {{ else }}
    {{ $og_image = "/img/icon-192.png" | absURL }}
    {{ $twitter_card = "summary" }}
  {{ end }}
  <meta property="twitter:card" content="{{ $twitter_card }}">
  {{ with $og_image }}<meta property="twitter:image" content="{{ . }}">
  <meta property="twitter:site" content="{{ . }}">
  <meta property="twitter:creator" content="{{ . }}">
  <meta name="twitter:image" content="{{ . }}">
  {{ end }}
  <meta property="og:site_name" content="{{ .Site.Title }}">
  <meta property="og:url" content="{{ .Permalink }}">
  <meta property="og:title" content="{{ if not .IsHome }}{{ .Title }} | {{ end }}{{ .Site.Title }}">
  <meta property="og:description" content="{{ $desc }}">
  {{- with $og_image }}<meta property="og:image" content="{{ . }}">{{end}}

What I meant is that you should instead add the meta property directly below the twitter:card property. So take the initial variant you had when asking this question, and change this:

  <meta property="twitter:card" content="{{ $twitter_card }}">
  {{ with .Site.Params.twitter }}

… into this:

  <meta property="twitter:card" content="{{ $twitter_card }}">
  {{ with $og_image }}<meta property="twitter:image" content="{{ . }}">{{end}}
  {{ with .Site.Params.twitter }}

In general I recommend you figure out how the HTML should look like (what the validator expects) and then run hugo serve for your local site and fiddle with the template until you get it. That way you get feedback faster and the bit of html and go template knowledge empowers you to do even more tweaks in the future. You probably only need to know the basic template syntax.

I hope this helps

Thanks for your advice, I’ll read up on the syntax and keep trying, hopefully, I will figure out a working solution.

Twitter should be using the og:image in Academic, as per the Twitter docs at https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/markup . If it’s not working, check that your BaseURL is correct in your config and that your image meets Twitter’s requirements. If there’s still an issue, you can reach out to the Twitter dev team.

2 Likes

Yes, you were correct it was an issue with the BaseURL that was causing the error. Thank you for help, it’s much appreciated.