Yoast SEO in Hugo

I made 3 headers in partial:

  1. header-home.html
  2. header-list.html
  3. header-single.html

header.home.html :

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="profile" href="http://gmpg.org/xfn/11" />
    <link type="text/css" media="all" href="{{ .Site.BaseURL }}wp-content/cache/autoptimize/css/{{ .Site.Params.css }}.css" rel="stylesheet" />

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}
    <title>{{ .Site.Title }} - page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }} - {{ .Site.Params.subtitle }}</title>
    {{ else }}
    <title>{{ .Site.Title }} - {{ .Site.Params.subtitle }}</title>
    {{ end }}

    <!-- This site is optimized with the Yoast SEO plugin v6.0 - https://yoast.com/wordpress/plugins/seo/ -->

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}{{ if $pag.HasPrev }}
    <meta name="robots" content="noindex,follow" />
    {{end}}

    <meta name="description" content="{{ .Site.Params.description }}" />
    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}<link rel="canonical" href="{{ .Paginator.URL | absURL}}" />
    {{ else }}
    <link rel="canonical" href="{{ .Permalink }}" />
    {{end}}

    {{ if .Paginator.HasPrev }}<link rel="prev" href="{{ .Paginator.Prev.URL }}" />{{end}}
    {{ if .Paginator.HasNext }}<link rel="next" href="{{ .Paginator.Next.URL }}" />{{end}}

    <meta property="og:locale" content="en_US" />
    <meta property="og:type" content="website" />

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}
    <meta property="og:title" content="{{ .Site.Title }} - page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }} - {{ .Site.Params.subtitle }}">
    {{ else }}
    <meta property="og:title" content="{{ .Site.Title }} - {{ .Site.Params.subtitle }}" />
    {{ end }}
    
    <meta property="og:description" content="{{ .Site.Params.description }}" />

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}
    <meta property="og:url" content="{{ .Paginator.URL | absURL}}" />
    {{ else }}
    <meta property="og:url" content="{{ .Permalink }}" />
    {{end}}

    <meta property="og:site_name" content="{{ .Site.Title }}" />
    <meta name="twitter:card" content="summary" />
    <meta name="twitter:description" content="{{ .Site.Params.description }}" />

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}
    <meta name="twitter:title" content="{{ .Site.Title }} - page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }} - {{ .Site.Params.subtitle }}">
    {{ else }}
    <meta name="twitter:title" content="{{ .Site.Title }} - {{ .Site.Params.subtitle }}" />
    {{ end }}

    <script type='application/ld+json'>
        {
            "@context": "http:\/\/schema.org",
            "@type": "WebSite",
            "@id": "#website",
            "url": "http:\/\/{{ .Site.Params.url }}\/",
            "name": "Opini",
            "potentialAction": {
                "@type": "SearchAction",
                "target": "http:\/\/{{ .Site.Params.url }}\/?s={search_term_string}",
                "query-input": "required name=search_term_string"
            }
        }

    </script>
    <script type='application/ld+json'>
        {
            "@context": "http:\/\/schema.org",
            "@type": "Person",
            "url": "http:\/\/{{ .Site.Params.url }}\/",
            "sameAs": [],
            "@id": "#person",
            "name": "{{ .Site.Title }}"
        }

    </script>
    <meta name="google-site-verification" content="{{ .Site.Params.gsv }}" />
    <!-- / Yoast SEO plugin. -->

header.list.html

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="profile" href="http://gmpg.org/xfn/11" />
    <link type="text/css" media="all" href="{{ .Site.BaseURL }}wp-content/cache/autoptimize/css/{{ .Site.Params.css }}.css" rel="stylesheet" />

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}
    <title>{{ .Title }} Archives - page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }} - {{ .Site.Title }}</title>
    {{ else }}
    <title>{{ .Title }} Archives - {{ .Site.Title }}</title>
    {{ end }}

    <!-- This site is optimized with the Yoast SEO plugin v6.0 - https://yoast.com/wordpress/plugins/seo/ -->

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}<meta name="robots" content="noindex,follow" />{{end}}

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}<link rel="canonical" href="{{ .Paginator.URL | absURL}}" />
    {{ else }}
    <link rel="canonical" href="{{ .Permalink }}" />
    {{end}}

    {{ if .Paginator.HasPrev }}<link rel="prev" href="{{ .Paginator.Prev.URL }}" />{{end}}
    {{ if .Paginator.HasNext }}<link rel="next" href="{{ .Paginator.Next.URL }}" />{{end}}

    <meta property="og:locale" content="en_US" />
    <meta property="og:type" content="object" />

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}
    <meta property="og:title" content="{{ .Title }} Archives - page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }} - {{ .Site.Title }}">
    {{ else }}
    <meta property="og:title" content="{{ .Title }} Archives - {{ .Site.Title }}" />
    {{ end }}

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}
    <meta property="og:url" content="{{ .Paginator.URL | absURL}}" />
    {{ else }}
    <meta property="og:url" content="{{ .Permalink }}" />
    {{end}}
    
    <meta property="og:site_name" content="Opini" />
    <meta name="twitter:card" content="summary" />

    {{ $pag := .Paginate (where .Data.Pages "Type" "post") }}
    {{ if $pag.HasPrev }}
    <meta name="twitter:title" content="{{ .Title }} Archives - page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }} - {{ .Site.Title }}">
    {{ else }}
    <meta name="twitter:title" content="{{ .Title }} Archives - {{ .Site.Title }}" />
    {{ end }}
    <script type='application/ld+json'>
        {
            "@context": "http:\/\/schema.org",
            "@type": "WebSite",
            "@id": "#website",
            "url": "http:\/\/{{ .Site.Params.url }}\/",
            "name": "Opini",
            "potentialAction": {
                "@type": "SearchAction",
                "target": "http:\/\/{{ .Site.Params.url }}\/?s={search_term_string}",
                "query-input": "required name=search_term_string"
            }
        }

    </script>
    <script type='application/ld+json'>
        {
            "@context": "http:\/\/schema.org",
            "@type": "Person",
            "url": "http:\/\/{{ .Site.Params.url }}\/{{ .Data.Plural | urlize }}\/{{ .Title | urlize }}\/",
            "sameAs": [],
            "@id": "#person",
            "name": "Opini"
        }

    </script>
    <meta name="google-site-verification" content="{{ .Site.Params.gsv }}" />
    <!-- / Yoast SEO plugin. -->

header.single.html

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="profile" href="http://gmpg.org/xfn/11" />
    <link type="text/css" media="all" href="{{ .Site.BaseURL }}wp-content/cache/autoptimize/css/{{ .Site.Params.css }}.css" rel="stylesheet" />
    <title>{{ .Title }} - {{ .Site.Title }}</title>

    <!-- This site is optimized with the Yoast SEO plugin v6.0 - https://yoast.com/wordpress/plugins/seo/ -->
    <meta name="description" content="{{ .Params.potongan | truncate 150 }}" />
    <link rel="canonical" href="{{ .Permalink }}" />
    <meta property="og:locale" content="en_US" />
    <meta property="og:type" content="article" />
    <meta property="og:title" content="{{ .Title }} - {{ .Site.Title }}" />
    <meta property="og:description" content="{{ .Params.potongan }}" />
    <meta property="og:url" content="{{ .Permalink }}" />
    <meta property="og:site_name" content="{{ .Title }}" />
    {{ range .Params.calon }}<meta property="article:calon" content="{{ . }}" />{{ end }}
    {{ range .Params.partai }}<meta property="article:partai" content="{{ . }}" />{{ end }}
    {{ range .Params.daerah }}<meta property="article:daerah" content="{{ . }}" />{{ end }}
    <meta property="article:published_time" content="{{ .Date.Format "2006-01-02" }}T{{ .Date.Format "15:04:05" }}+07:00" />
    <meta property="og:image" content="{{ .Site.BaseURL }}wp-content/uploads/{{ .Params.gambar }}.jpg" />
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:description" content="{{ .Params.potongan }}" />
    <meta name="twitter:title" content="{{ .Title }} - {{ .Site.Title }}" />
    <meta name="twitter:image" content="{{ .Site.BaseURL }}wp-content/uploads/{{ .Params.gambar }}.jpg" />
    <script type='application/ld+json'>
        {
            "@context": "http:\/\/schema.org",
            "@type": "WebSite",
            "@id": "#website",
            "url": "http:\/\/{{ .Site.Params.url }}\/",
            "name": "Opini",
            "potentialAction": {
                "@type": "SearchAction",
                "target": "http:\/\/{{ .Site.Params.url }}\/?s={search_term_string}",
                "query-input": "required name=search_term_string"
            }
        }

    </script>
    <script type='application/ld+json'>
        {
            "@context": "http:\/\/schema.org",
            "@type": "Person",
            "url": "http:\/\/{{ .Site.Params.url }}\/{{ .Title | urlize }}\/",
            "sameAs": [],
            "@id": "#person",
            "name": "{{ .Site.Title }}"
        }

    </script>
    <meta name="google-site-verification" content="{{ .Site.Params.gsv }}" />
    <!-- / Yoast SEO plugin. -->
3 Likes
{{ $pag := .Paginate (where .Data.Pages "Type" "post") }}{{ if $pag.HasPrev }}
<meta name="robots" content="noindex,follow" />
{{end}}

I don’t think it’s good practice to use the values noindex,follow for paginated pages.

Does hugo use the correct html automatically or do you have an if statement to include it?

I have everything in a single file with a bunch of conditions:

Agreed, it should be index, follow and then make sure the rel next, rel previous markup is all setup.

Edit: Also, another place people go wrong is having the canonical set for all paginated pages to the first page. These should be set to the respective pages.

1 Like

Also it’s not really DRY to have 3 different <head> partials.

I can understand why people are doing it. Getting the right context with Go templates is hard.

But I’ll post a tips & tricks on getting the context of Hugo Paginated Pages soon.