Adding (Limited) Pagination to Hugo

Adding (Limited) Pagination to Hugo

This post is more than 2 years old.

This is probably only going to be useful to a limit audience but I thought I'd share. When converting my site from WordPress to Hugo I discovered that the built-in pagination support was a bit problematic for my site. Why? I have a large amount of content and at the default page size, I ended up with over five hundred pages of - well - pages.

To me - the solution was simple. Just get rid of the pagination. Frankly, I rarely "page back" to see older content. Heck, I rarely visit a blog's home page anyway. I'm typically on a blog because of a Google search result. Recently though I found myself trying to get links for my own content from a week or so ago and wanting to do a bit of paging. I did some basic research into how I could add pagination, but only for a limited subset of my content, say five pages or so. This is how I did it.

First, I edited the main pagination partial. My copy was blank as I didn't want pagination at all, so I copied the version from my theme and added a bit of logic.

{{ if lt .Paginator.PageNumber 5 }}
	<nav id="page-nav">
	{{ if or (.Paginator.HasPrev) (.Paginator.HasNext) }}
		{{ if .Paginator.HasPrev }}
			<a class="extend prev" rel="prev" href="{{.Paginator.Prev.URL}}">
				« {{with .Site.Data.l10n.pagination.previous}}{{.}}{{end}}
		{{ end }}
		{{ if .Paginator.HasNext }}
			<a class="extend next" rel="next" href="{{.Paginator.Next.URL}}">
				{{with}}{{.}}{{end}} »
		{{ end }}
	{{ end }}
{{ end }}

Even if you've never seen Go templates and Hugo before, you can probably figure out what's going on here. My change was literally just the IF condition wrapping the logic. I chose 5 as the total number of pages but you could use any number here.

The next change was in the article_list partial. My code was initially this:

{{ range first 10 (where .Site.Pages "Type" "post") }}

Again - I assume if you've never seen Go/Hugo before you can guess as to the logic here. The default code uses pagination and had looked like this before I removed it:

{{ $paginator := .Paginate (where .Site.Pages "Type" "post") }}
{{ range $paginator.Pages }}

So my goal was to bring pagination back, but to limit it to the subset of posts that would be covered by the 5 pages of content I wanted to support. Here is what I came up with:

{{ $paginator := .Paginate ((first 50 (where .Site.Pages "Type" "post"))) }}
{{ range $paginator.Pages }}

Obviously that's a bit of a hack. In theory I could use a site-wide variable and handle both parts dynamically, but for now, this is what worked for me.

Actually, it didn't quite work. It seemed fine when I tested, but when I generated my static output, I was getting a huge amount of additional pages due to pagination. I posted on the forums and actually got support from the developer who implemented pagination for Hugo. That's what I call good support!

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate for HERE Technologies. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA