Add rel previous/next link to Webflow sites using pagination
Clone an example from Made in Webflow:
https://webflow.com/made-in-webflow/website/pagination-and-rel-next-previous
Google's documentation on rel previous/next
Something that a Webflow customer may run into if they're using pagination on a CMS list is a duplicate pages error in Google's Search Console. Webflow uses URL parameters to handle pagination. For example, if I had a paginated CMS list in Webflow on my blog page (site.webflow.io/blog), when I hit the next button to get page two my URL will be site.webflow.io/blog?3f5c39bb_page=2. It's the same URL, only we have that URL param added at the end.
What Google looks for on pages like this to prevent being flagged as duplicates is having rel next/previous links added to the head of the document. This doesn't exist natively inside of Webflow, but we can fis this with some custom code on our page.
Inside of your Webflow project, head on over to your paginated list and give your pagination buttons the same class. In this example we're using pagination-button
. While you're there, you need to add some custom attributes to these buttons.
Select the Next
button and click on the settings panel or press d
on your keyboard. Scroll down to the Custom attributes section and click the plus button to add a new attribute.
For the name, we'll use data-rel
and for the value we'll add next
. Now click through to the second page in your list in the Designer so that the previous button is visible. We'll follow the same pattern here and add a new attribute here as well with the name data-rel
and the value will be previous
.
That's it for Webflow settings, now we can move onto the custom code.
Now in the Before </body>
code section in page settings add the following code:
<script>
const paginationButtons = document.querySelectorAll(".pagination-button");
window.onload = (event) => {
paginationButtons.forEach((button) => {
createRel(button.dataset.rel, button.href);
});
};
function createRel(type, href) {
const link = document.createElement("link");
link.href = href;
link.rel = type;
document.head.appendChild(link);
}
</script>
This code is also available in this repo in the file script.js
. Let's look at the code and break it down.
First, we're setting a variable that includes all of our pagination buttons:
const paginationButtons = document.querySelectorAll(".pagination-button");
Then, we have a function to create our links that has two parameters:
- type - this will be previous or next and gets pulled from our data attribute on the pagination button
- href - the link to the next or previous page that comes from our paggination button
The function looks like this:
function createRel(type, href) {
// create the link element
const link = document.createElement("link");
// set the href for the link as the same on the button
link.href = href;
// set the type from the custom attribute on our button
link.rel = type;
// append it to the head on the page
document.head.appendChild(link);
}
Then, when the page loads, we're running this function for each button:
window.onload = (event) => {
paginationButtons.forEach((button) => {
createRel(button.dataset.rel, button.href);
});
};
Now once we publish we'll have rel previous/next links available. You can double check in the Mobile-Friendly Test tool from Google to verify their crawler will see these dynamically created links.
We've seen some awesome solutions to this in the community. Big shouts to Forrest Oliphant for this solution using pjax:
https://discourse.webflow.com/t/seamless-pagination-with-pjax/75284
But, for us, this solution won't work because since it's replacing content in the frame, it's not changing the head of the document. We could add some additional code here to implement this solution, but instead we have an addtional option using the scrollIntoView
method.
First, we're adding some new Global variables that we'll comment here in this snippet:
// the section that contains your paginated list
const paginationSection = document.querySelector("#pagination");
// getting the parameters for the page
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
// creating a new regular expression that will look for Webflow's pagination parameters
const newExpression = new RegExp("([a-f0-9]{8})_page");
Then we add an if statement to the work happening when the page loads to check and see if pagination is happening. It looks like this:
// if Webflow pagination is in our params
if (newExpression.test(urlParams)) {
//scroll to our paginated section
paginationSection.scrollIntoView({ block: "start" });
// lets think about accessibility
// set the tabindex of the section to -1
// lets focus this paginated section for screeen readers
paginationSection.setAttribute("tabindex", "-1");
paginationSection.focus();
}