HOWTO: Pagination SEO Markup (Correct canonical \ rel next \ rel prev markup)

OK, there are a couple of things to note here, but first here is an Article from Google affirming everything I am about to say - https://webmasters.googleblog.com/2011/09/pagination-with-relnext-and-relprev.html

Rel Canonical

The default pagination functionality does not alter the rel=“canonical” markup. Therefore a default implementation will point all pagination pages to page 1 (it actually does not implement canonical at all, but I am presuming you did not alter your base template here). This is WRONG.

Here is a simple fix:

{{ if gt .Paginator.Pages 1}}
<link rel="canonical" href="{{ .Paginator.URL }}"> {{else}}
<link rel="canonical" href="{{ .Permalink }}">
{{ end }}

or just more simply:

 <link rel="canonical" href="{{ .Paginator.URL }}">

Rel="next \ rel=“prev”

When using pagination, you should indicate to Google the next and previous pages in the head as markup.

This code will do that:

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

Obviously, if you try to put these snippets of code on a page that doesn’t use pagination it will throw errors.

3 Likes

I think you must use the isset template function https://gohugo.io/templates/functions#isset

Something like this

 <link rel="canonical" href="{{ .Permalink }}">
    {{ if (isset .Paginator.HasPrev ) }}
      <link rel="prev" href="{{ .Paginator.Prev.URL  }}">
    {{ end }}

Wow, I’m surprised there isn’t more activity on this thread! Good stuff. Just tuned up my website’s meta tags for both canonicalization and rel next/prev. Validated everything with the Screaming Frog SEO Spider (free for small sites).

As you eluded to above, I had to make sure I initialized my Paginator earlier in the template hierarchy, otherwise my paginator wasn’t ready when rendering the page .

My baseof.html template now has a block that looks like this:

{{ if and .Params.paginate .Paginator }}
  <link itemprop="url" rel="canonical" href="{{ .Paginator.URL }}">
  {{ if .Paginator.HasNext }}
    <link rel="next" href="{{ .Paginator.Next.URL }}" />
  {{end}}
  {{ if .Paginator.HasPrev }}
    <link rel="prev" href="{{ .Paginator.Prev.URL }}" />
  {{end}}        
{{ else }}
  <link itemprop="url" rel="canonical" href="{{ .Permalink }}"/>
{{ end }}

and higher up at the top of my baseof.html template I have a block like this:

{{ if .Params.paginate }}
  {{ $paginator := (.Paginator .Params.paginate) }}
{{ end }}

This way I can turn on and off pagination anywhere with front matter and specify the page size. So in my taxonomies I can add a cascading front matter paginate: 4 and that will prepare the paginator with page size 4. Likewise I can add something like paginate: false to a page like my home page to suppress pagination at the root (I’d rather you click into a recent article, category or topic/tag).

It seems to be working well for me - but I’m always open to suggestions or comments to help make it better!

I’m sad to say that about a year or two ago Google confirmed that they don’t use rel=next or rel=prev anymore. See https://twitter.com/johnmu/status/1108719402558590976?lang=en

Doesn’t hurt to add them though in case other search engines still do.

Thanks @Jonathan_Griffin, while google is on the list of reasons I might do things, it is certainly not the exclusive reason for anything on my site. :upside_down_face:

I believe this article is in response to that 2019 tweet:

But yes there are dozens of “signals” these days as we sprinkle our markup with opengraph tags, twitter tags, rich data snippets (RDFa/microdata), json+ld, sitemaps, atom/rss feeds, etc. I’m sure google can figure it out without my rel next/prev tags.

Really nice post, it’s already helping me.

@Nyala

Are you a chatbot?

@alexandros why did you decide that? I’m just newbie

I did not decide anything. Only asked a question.

The above solutions ended up in the error “at <.Paginator.HasPrev>: error calling HasPrev: runtime error: invalid memory address or nil pointer dereference” for me. The file where I added the above codes and my below code is head.html

The following code worked for me.

    {{- if .Paginator }}
    {{- if .Paginator.HasPrev }}
    <link rel="prev" href="{{ .Paginator.Prev.URL | absURL }}" />
    {{- end }}
    {{- if .Paginator.HasNext }}
    <link rel="next" href="{{ .Paginator.Next.URL | absURL }}" />
    {{- end }}
    <link rel="canonical" href="{{ .Paginator.URL | absURL }}" />
    {{- else }}
    <link rel="canonical" href="{{ .Permalink }}" />
    {{- end }}