How to add a "load more" button to your blog

seven

Caleb O.

Posted on March 6, 2023

How to add a "load more" button to your blog

Last week, I added some features to my blog. From the preloader that utilized Next.js' router API, to the search and Table of Content component.

Recently, I've just added a minor feature that allows me to conditionally render a certain amount of articles on my blog. Instead of having all the articles I've written all at once on the page.

This feature is a bit common on some developer blogging platforms., and building it was a bit straightforward since I knew what needs to be done.

The idea behind it is for us to have an initial amount of articles listed whenever anyone navigates to the blog route. So, a variable like the one below should suffice

const initialPostList = 6
Enter fullscreen mode Exit fullscreen mode

And whenever a visitor clicks on the "load more" button, a callback function is triggered to increment the number of articles/posts on the blog.

It'll be ideal to also have another variable that holds the increment value. A variable like the one below should work fine.

const incrementInitialPostList = 4
Enter fullscreen mode Exit fullscreen mode

Watching the state

The snippets in the previous section are of great importance to this feature. initialPostList holds the amount of articles we want on initial render of the blog page, while incrementInitialPostList holds the value with which the articles list would be incremented.

With that said, some of the snippets here may look unfamiliar or intricate. If you happen to feel this way, when you're reading this, I'd implore you to check out this article that walks you through how to build a Next.js blog

I'm assuming you already have an idea of some Next.js data-fetching patterns, If not, please, take a look at the link I shared in the paragraph above.

I needed a way to keep these values — initialPostList and incrementInitialPostList — in the blog component's state, so that I can tap into its lifecycle methods .

The snippet below shows what the Blog component looks like.

import Article from './Article'; // Replace with your own Article component

const initialPostList = 6; // Number of articles to display initially
const incrementInitialPostList = 4; // Number of articles to add each time the "load more" button is clicked

export default function Blog() {
  const [displayPosts, setDisplayPosts] = React.useState(initialPostList);
  const [articles, setArticles] = React.useState(/* Your array of articles goes here */);

  const loadMore = () => {
    setDisplayPosts(displayPosts + incrementInitialPostList)
  }

  return (
    <div>
      {articles.slice(0, displayPosts).map(article => (
        <Article key={article.id} article={article} />
      ))}
      {displayPosts < articles.length ? ( 
          <button onClick={handleLoadMore}>Load More</button>
      ) : null}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Rendering more posts

In the snippet from the previous section, I'm using initialPostList variable to render the first 6 articles and adding the incrementInitialPostList variable to represent the number of articles to render each time the "load more" button is clicked.

The loadMore function simply updates the displayPosts state variable with the new value.

The articles array can come from any data source you like (e.g. an API endpoint, a static file, etc.), and you can customize the Article component to match the structure of your data.

But, in this case, it is coming from a markdown source, and I can get the list of articles with getStaticProps, a data-fetching method of Next.js

The blog component is modified like so;

export default function Blog({ posts }) {
  const [displayPosts, setDisplayPosts] = React.useState(initialPostList);
  const [articles, setArticles] = React.useState(posts);

  const loadMore = () => {
    setDisplayPosts(displayPosts + incrementInitialPostList)
  }

  return (
    <div>
      {articles.slice(0, displayPosts).map(article => (
        <Article key={article.id} article={article} />
      ))}
      {displayPosts < articles.length ? ( 
          <button onClick={loadMore}>Load More</button>
      ) : null}
    </div>
  );
}

export async function getStaticProps() {
  let articles = await getAllArticles()

  const sortedArticles = articles.map((article) => article)

  sortedArticles.sort((a, b) => {
    return new Date(b.publishedAt) - new Date(a.publishedAt)
  })

  return {
    props: {
      posts: sortedArticles,
    },
  }
}
Enter fullscreen mode Exit fullscreen mode

The slice function is used to only display the first item in the posts array through the value of the displayPosts value — which is 6 — from the articles array.

The displayPosts < articles.length condition is used to check if there are more articles to display and show the "load more" button accordingly.

From @nlxdodge's comment below, I found an approach that helps you preserve the state when you navigate to, and away from the page.

Take a look at it here

💖 💪 🙅 🚩
seven
Caleb O.

Posted on March 6, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related