skip to Main Content
  1. 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.

  2. 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.

  1. 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,
   

    },
  };
}





  1. 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;
}



  1. 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
        }
      }
    }
  }
`;

  1. Here is what our console looks like.

enter image description here

2

Answers


  1. 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 and startAfter params. by default when the user requests without startAfter params return blogs as a limit.

    if startAfter param is available then send blogs those ids come after startAfter value.

    /blogs?limit=10 => return top 10 blogs
    /blogs?limit=10&startAfter=10 => return next 10 blogs (where 10 is last blog id)
    

    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 sending startAfter param. stop requesting if the server sends back an empty array.

    export default function Blogs({ posts }) {
        const [blogs, setBlogs] = useState(posts)
        
        const loadMorePost = useCallback(() => {
           const makeReq = async ()=> {
               const res = await fetch(`/blogs?limit=10&startAt=${blogs.at(-1).id}`)
               const json = await res.json()
               // TODO: stop fetching if response is empty array
               setBlogs(blogs => [...json, blogs])
           }
        }, [blogs])
        
        return <> 
          {/* ... */}
          <button onClick={loadMorePost}>load more</button>
        </>
    
    }
    

    Appendix

    for reference, you can check how I implemented pagination in my app.

    Login or Signup to reply.
  2. 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 or startAfter):

    posts(offset: $offset, limit: $limit) {
    

    and the back-end API function should be modified in order to allow those params

    export async function getBlogPosts(offset, limit) {
        const data = await fetchAPI(blogPosts, { variables: { offset, limit} });
        return data;
     }
    

    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:

    const PAGE_SIZE = 100
    let current_page = 0
    
    export async function getStaticProps() {
        current_page += 1
        const offset = PAGE_SIZE * current_page
        const limit = offset + PAGE_SIZE 
    
        const posts = await getBlogPosts(offset, limit );
    
        return ...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search