-
We Built our blog on Next JS, using WordPress as our API, we added content till we got to over 500 and our blog kept crashing because we had to call all our blog posts at the same time from the server.
-
We intend to create a "Load More" Pagination button function that calls only a specific number of objects at a time when clicked.
Here is what our code looks like.
- Blog index
//index.tsx
/**
* Caution: Consider this file when using NextJS or GatsbyJS
*
* You may delete this file and its occurrences from the project filesystem if you are using react-scripts
*/
import React from 'react';
import BlogSearch from 'views/BlogSearch';
import Main from 'layouts/Main';
import WithLayout from 'WithLayout';
import Head from 'next/head';
import { getBlogPosts } from '../../lib/api';
const BlogPage = ({ posts }): JSX.Element => {
return (
<>
{' '}
<Head>
<title>Copy and Post - Blog</title>
<meta
property="og:title"
content="Copy and Post - Blog"
key="Copy and Post"
/>
</Head>
<WithLayout
component={() => <BlogSearch posts={posts} />}
layout={Main}
/>
</>
);
};
export default BlogPage;
export async function getStaticProps() {
const posts = await getBlogPosts();
return {
props: {
...posts,
},
};
}
- Our API functionality.
//api.ts
import { homepageQuery, blogPosts, blogPostBySlug } from './queries';
const API_URL = process.env.WP_API_URL;
async function fetchAPI(query, { variables = {} } = {}) {
// Set up some headers to tell the fetch call
// that this is an application/json type
const headers = { 'Content-Type': 'application/json' };
// build out the fetch() call using the API_URL
// environment variable pulled in at the start
// Note the merging of the query and variables
const res = await fetch(API_URL, {
method: 'POST',
headers,
body: JSON.stringify({ query, variables }),
});
// error handling work
const json = await res.json();
if (json.errors) {
console.log(json.errors);
console.log('error details', query, variables);
throw new Error('Failed to fetch API');
}
return json.data;
}
export async function getHomepageSections() {
const data = await fetchAPI(homepageQuery);
return data;
}
export async function getBlogPosts() {
const data = await fetchAPI(blogPosts);
return data;
}
export async function getBlogPostBySlug(slug) {
const data = await fetchAPI(blogPostBySlug, { variables: { id: slug } });
return data;
}
- Finally our Query function.
//query.ts
export const homepageQuery = `
query HomepageQuery {
homepageSections {
edges {
node {
homepage {
hero {
animatedwords
heading
subtitle
}
callouts {
title
subtitle
calloutone {
title
subtext
image {
mediaItemUrl
}
}
calloutthree {
title
subtext
image {
mediaItemUrl
}
}
callouttwo {
title
subtext
image {
mediaItemUrl
}
}
}
icongrid {
iconone {
description
icon
title
}
iconfive {
description
icon
title
}
iconfour {
description
icon
title
}
iconsix {
description
icon
title
}
iconthree {
description
icon
title
}
icontwo {
description
icon
title
}
}
}
}
}
}
}
`;
export const blogPosts = `
query BlogPosts {
posts(first: 1000) {
edges {
node {
author {
node {
nickname
}
}
date
slug
featuredImage {
node {
mediaItemUrl
}
}
title
}
}
}
}
`;
export const blogPostBySlug = `
query PostBySlug($id: ID!) {
post(id: $id, idType: SLUG) {
id
content
title
author {
node {
nickname
avatar {
url
}
}
}
date
featuredImage {
node {
mediaItemUrl
}
}
}
}
`;
- Here is what our console looks like.
2
Answers
Implementing ‘load more’ pagination is not a simple task. I’ll just give a basic overview of how you can implement it on both the client and server sides.
Server Side
You should have an API end-point that takes
limit
andstartAfter
params. by default when the user requests withoutstartAfter
params return blogs as a limit.if
startAfter
param is available then send blogs those ids come afterstartAfter
value.Client Side
On the client side, fetch some initial blogs in
getStaticProps
function then whenever the user completes scrolling or click on load more button fetch new blogs by sendingstartAfter
param. stop requesting if the server sends back an empty array.Appendix
for reference, you can check how I implemented pagination in my app.
I think you can use the offset and limit as vars for your back-end query. something like this (not sure if it is called
offset
orstartAfter
):and the back-end API function should be modified in order to allow those params
and store the current page on the client side.
on the client side, if you click the "load more" button, you can execute the limits calculation like this: