I have a custom code solution. Paste it into your pages or websites before body tag. It overrides webflows native pagination rules. I use it inside a Tabs section where I have paginated CMS lists under each tab. Dont forget to add script tags before and after the code:
`
document.addEventListener(‘DOMContentLoaded’, function() {
const tabsContent = document.querySelector(‘.w-tab-content’);
const tabLinks = document.querySelectorAll(‘.w-tab-link’);
let currentTab = tabLinks[0].getAttribute(‘data-w-tab’);
let cachedContent = {};
function debug(message) {
console.log([DEBUG]: ${message}
);
}
function captureAllPaginationClicks() {
debug(‘Capturing all pagination clicks’);
document.addEventListener(‘click’, function(e) {
const paginationLink = e.target.closest(‘.w-pagination-wrapper a’);
if (paginationLink) {
e.preventDefault();
e.stopPropagation();
handlePaginationClick(e, paginationLink);
}
}, true); // Use capture phase
}
async function handlePaginationClick(e, link) {
debug(Pagination click detected
);
const url = new URL(link.href, window.location.origin);
const pageParam = link.getAttribute('data-page') || url.searchParams.get('page');
if (pageParam) {
url.searchParams.set('page', pageParam);
}
const cleanUrl = url.toString();
debug(`Clean URL for pagination: ${cleanUrl}`);
showLoadingIndicator();
try {
await fetchAndCachePage(cleanUrl, currentTab);
updateContent(cleanUrl);
} catch (error) {
debug(`Error during pagination: ${error}`);
} finally {
hideLoadingIndicator();
}
}
async function fetchAndCachePage(url, tabId) {
debug(Fetching and caching: ${url} for tab: ${tabId}
);
try {
const response = await fetch(url);
const text = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(text, ‘text/html’);
const content = doc.querySelector(`.w-tab-pane[data-w-tab="${tabId}"] .w-dyn-items`);
const pagination = doc.querySelector(`.w-tab-pane[data-w-tab="${tabId}"] .w-pagination-wrapper`);
if (content) {
if (!cachedContent[url]) cachedContent[url] = {};
cachedContent[url][tabId] = {
content: content.innerHTML,
pagination: pagination ? pagination.outerHTML : ''
};
debug(`Cache updated for: ${url}, tab: ${tabId}`);
} else {
debug(`Content not found for tab: ${tabId}`);
}
} catch (error) {
debug(`Error fetching page: ${error}`);
}
}
function updateContent(url) {
debug(Updating content for tab: ${currentTab}
);
const activePane = tabsContent.querySelector(.w-tab-pane[data-w-tab="${currentTab}"]
);
if (!activePane) {
debug(Active pane not found for tab: ${currentTab}
);
return;
}
const contentContainer = activePane.querySelector(‘.w-dyn-items’);
let paginationContainer = activePane.querySelector(‘.w-pagination-wrapper’);
if (cachedContent[url] && cachedContent[url][currentTab]) {
contentContainer.innerHTML = cachedContent[url][currentTab].content;
if (paginationContainer) {
paginationContainer.outerHTML = cachedContent[url][currentTab].pagination;
} else if (cachedContent[url][currentTab].pagination) {
contentContainer.insertAdjacentHTML('afterend', cachedContent[url][currentTab].pagination);
}
debug(`Content updated for tab: ${currentTab}`);
} else {
debug(`No cached content found for tab: ${currentTab}`);
}
}
function showLoadingIndicator() {
const activePane = tabsContent.querySelector(.w-tab-pane[data-w-tab="${currentTab}"]
);
const contentContainer = activePane.querySelector(‘.w-dyn-items’);
contentContainer.style.opacity = ‘0.5’;
}
function hideLoadingIndicator() {
const activePane = tabsContent.querySelector(.w-tab-pane[data-w-tab="${currentTab}"]
);
const contentContainer = activePane.querySelector(‘.w-dyn-items’);
contentContainer.style.opacity = ‘1’;
}
tabLinks.forEach(link => {
link.addEventListener(‘click’, function() {
currentTab = this.getAttribute(‘data-w-tab’);
debug(Tab changed to: ${currentTab}
);
});
});
function initializePagination() {
debug(‘Initializing pagination script’);
captureAllPaginationClicks();
fetchAndCachePage(window.location.href, currentTab)
.then(() => {
debug(‘Initial content cached’);
})
.catch(error => {
debug(Error during initialization: ${error}
);
});
}
// Initialize immediately and after a short delay
initializePagination();
setTimeout(initializePagination, 1000);
// Mutation Observer to detect when tabs are fully loaded
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === ‘childList’ && mutation.addedNodes.length > 0) {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(‘w-tab-pane’)) {
debug(‘Tab content loaded, reinitializing pagination’);
initializePagination();
}
});
}
});
});
observer.observe(tabsContent, { childList: true, subtree: true });
});