Adding Fragments to WordPress Pagination URLs

May 16, 2020

I recently added pagination to the posts page of this site after realizing that I’d forgotten it. I was prepared to spend a few minutes with the previous_posts_link() and next_posts_link() and call it a day. But, much like life itself, my best laid plans hit a snag.

That snag is my homepage design. I decided to do this weird fixed position panel that gets covered by the posts archive on scroll.

Whether it’s good or bad UX is up for debate, but that’s not the point.

I added an anchor link called #top right above the posts archive. That way, I can link directly to posts from, say, my main navigation.

The problem is that WordPress pagination links aren’t aware of that anchor. So, when adding the previous and next links to the archive, the properly jumped me from page to page, but the posts were below the fixed panel each time. No bueno.

I thought I’d have to resort to some sort of JavaScript solution. I’m always hesitant to do that for something like this because it feels like a one-off hack.

That’s when I learned about the paginate_links() function in WordPress.

It takes an argument that allows you to add a fragment to the URL. Something like this:

paginate_links(
  array( 
    'add_fragment' => '#top'
  ) 
);

That worked! My links now go directly to the blog rather than the fixed panel. But, the thing about paginate_links() is that it not only returns the previous and next links, but page numbers as well. That’s not what I really wanted. Thankfully, the function includes arguments that can add markup before and after the page numbers. I wrapped each one in a span that I used to hide them in CSS, along with aria-hidden to make sure they were ignored by screen readers as well.

Here’s how my snippet wound up looking:

paginate_links(
  array( 
    'add_fragment' => '#top'
    'before_page_number'=> '<span class="hide" aria-hidden="true">',
    'after_page_number'=> '</span>',
    'next_text'    => 'Older Posts',
    'prev_text'    => 'Newer Posts'
  ) 
);
There we go, that’s the stuff!