Understanding Pagination - A Guide for Technical SEOs

In the following guide we're going to discuss pagination and what's actually going on behind the scenes.

It's actually really simple and understanding it better will hopefully empower you to speak more confidently about it. While I've focused on pagination, specifically, the same is true for how faceted navigation works from a coding point of view.

I say this because I know a lot of people fear parameters, which are arguably the most common and in my opinion best way to do it.

A Bridge Between SEOs and Developers

Personally, I've always found if I can understand something from all angles, my fear of it goes away. I can talk about it more confidently. I have more empathy for the people who are making the changes and better understand the challenges they're facing. Heck, I've even been able to give developers the answers to their problems from time to time - I'm not the type of person to speak confidently about something I don't really understand; who are these annoying people?

For SEOs, if we can understand the inner workings of, in this case, pagination, we can help foster communication with developers. It empowers us SEOs to discuss technical requirements confidently, recognise potential SEO challenges, and provide informed solutions. Conversely, it can also help developers understand the SEO implications of their work, creating a more productive dialogue and collaboration between the two roles.

With this in mind let's deep-dive into pagination, this is a technical post to help you better understand the inner workings of pagination - again, this is applicable to faceted navigations, too. To be clear, this isn't a strategic post, I've added some resources for that at the end though.

While I'm going to be giving code examples in this post, you don't need to be a coder, the examples, while (hopefully) accurate, are fully commented on, explained and kept nice and simple; enough to give you the basic idea of how it works.

If you are worried about the code, just read through the comments line by line and it will make sense after a little head-scratching 😁

Let's code up!

Note: We are going to be using Flask for this, you can read up more about it here, if you're interested.

In our example, we are going to look at a category page which displays products, 10 at a time.

Our example URL will be /category

The backend code for this page is as follows:

This code does the following:

  1. It imports the necessary Flask modules.
  2. It creates a Flask app and connects to the database.
  3. It defines a route called /category that displays a list of items from the database.
  4. It gets the page number from the query parameter called page. If no page parameter is specified, it defaults to 1.
  5. It sets the number of items to display per page (in this case, 10).
  6. It calculates the offset for the SQL query based on the page number and the number of items per page. For example, if the page number is 2 and there are 10 items per page, the offset would be 10. This ensures that the correct set of items is retrieved from the database.
  7. It executes a SQL query to retrieve the items for the current page, using the LIMIT
    and OFFSET clauses to specify the number of items to return and the starting position.
  8. It renders a template with the items and the current page number passed into the template.
  9. app.run() simply starts the Flask app.

So, when we go to /category?page=1, the number, in this case, 1, is parsed and passed into our SQL.

A 'real' example of pagination.
A 'real' example of pagination.

What's the SQL bit doing?

The LIMIT and OFFSET clauses in SQL are used to limit the number of rows returned by a query and to specify the starting position of the rows to return.

Here is an example of how LIMIT and OFFSET work, using a table with 8 rows:

If we wanted to retrieve the first 3 rows of this table, we could use the following query:

This would return the following rows:

If we wanted to retrieve the next 3 rows after the first 3 (i.e. rows 4 through 6), we could use the following query:

This would return the following rows:

The LIMIT clause specifies the maximum number of rows to return, and the OFFSET clause specifies the number of rows to skip before starting to return rows. In this example, the LIMIT clause specifies that we want to return 3 rows and the OFFSET clause specifies that we want to skip the first 3 rows, so the query returns rows 4 through 6.

So you see, when clicking through a paginated series, the incremented number is passed into the backend and the correct products are then returned.

Now with our new knowledge, let's have a look at a possible faceted navigation example:

This code does the following:

  1. It imports the necessary Flask modules.
  2. It creates a Flask app and connects to the database.
  3. It defines a route called /products that displays a list of products from the database, filtered by brand if a brand is selected.
  4. It gets the selected brand from the query parameter. If no brand is specified, it defaults to None
  5. It queries the database for all distinct brands in the products table.
  6. If a brand was selected, it queries the database for products by that brand. Otherwise, it queries the database for all products.
  7. It renders a products.html template with the products and brands, along with the selected brand.
  8. It starts the Flask app.

Wrapping up

Hopefully, you've found that useful and now have a better idea about how pagination (and faceted navigation) works.

Recommended Reading: If you want a post on optimising pagination then I'd recommend this guide or this guide.

If you want to work with your developers better, I suggest reading The SEO Sprint

And of course, you should check out this post from Google.

join our Newsletter

We periodically send updates. No spam, just the good stuff.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
let’s start

Ready to take your sEO to the next level?

Free trials require a credit or debit card (to help prevent abuse). Payments are handled via Stripe. You can cancel anytime via the dashboard.