Is it possible to implement pagination using 'useSWR' in combination with the contentful-client?

I am currently working on implementing pagination in a Next.js project using the useSWR hook. My approach seems to be functioning correctly, but I have a concern about caching due to the key parameter not being a unique string as recommended in the documentation.

Instead of passing a URL as the key, I am simply using the index to fetch the appropriate data. Will this affect the caching mechanism? I am unsure if I am following best practices here?

index.js

import React, { useState } from 'react'
import Page from '../components/page'

export default function IndexPage( ) {
  const [pageIndex, setPageIndex] = useState(0)

  return (
    <div>
      <Page index={pageIndex} />
      <button onClick={() => setPageIndex(pageIndex - 1)}>Previous</button>
      <button onClick={() => setPageIndex(pageIndex + 1)}>Next</button>
    </div>
  )
}

And in my page.js

import useSWR from 'swr'
import { fetcher } from '../client/fetcher'

function Page({ index }) {
  const { data } = useSWR(index, fetcher)
  console.table(data)

  return <div>nothing here, just testing</div>

}

export default Page

And finally the fetcher.js

import client from './contentful-client'

export async function fetcher(pageIndex = 1, limit = 3) {
  const data = await client.getEntries({
    content_type: 'posts',
    skip: pageIndex * limit,
    order: '-fields.publishDate',
    limit,
  })

  if (data) {
    return data
  }
  console.log('Something went wrong fetching data')
}

Answer №1

For enhanced security, it is recommended to relocate the Contentful data fetching logic to the server instead of exposing credentials and logic in the browser. This can be achieved by utilizing Next.js API routes.

// pages/api/posts.js

import client from '<path-to>/contentful-client' // Adjust the path accordingly

export default async function handler(req, res) {
    const { pageIndex = 1, limit = 3 } = req.query
    const data = await client.getEntries({
        content_type: 'posts',
        skip: pageIndex * limit,
        order: '-fields.publishDate',
        limit,
    })

    res.json(data)
}

To streamline your code structure, you can update your page to send a request to the new API route. Simply pass the route URL as a parameter to useSWR.

import useSWR from 'swr'

const fetcher = (url) => fetch(url).then(res => res.json())

function Page({ index }) {
    const { data } = useSWR(`/api/posts?pageIndex=${index}`, fetcher)
    console.table(data)

    return <div>nothing here, just for testing</div>
}

export default Page

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Something went wrong with the API: an error occurred where headers were sent to the client before they could be set

Recently, I've encountered an issue where users are facing errors during registration or login. The error message pops up occasionally and here is a screenshot of it: https://i.sstatic.net/zum1u.png Below is the code snippet that I'm using: htt ...

What are some effective methods for locating dual edges within a Half-Edge (DCEL) data structure?

I have implemented a HalfEdge data structure to represent the connectivity between faces in my mesh. While importing an external model, I construct the HalfEdge structure. However, for meshes with numerous triangles, the construction process is time-consu ...

Trouble encountered while trying to show information on Tooltip using AngularStrap

I've been attempting to show some information in a Tooltip, but all I see is the Title displayed like this: Below is the HTML code where I'm calling it: <button class="btn btn-primary" type="bu ...

Creating a banner image that scrolls while maintaining a fixed size

I'm looking to add a banner image with a scrolling effect as users navigate down the page, but I'm not sure what this technique is called. An example of what I'm trying to achieve can be seen on this site. As the user scrolls down, the res ...

Modifying the HTML <select> element with JavaScript

[resolved] I'm encountering an issue with the code below that is supposed to dynamically change the options in a second drop-down menu based on the selection made in the first menu. I've tried to troubleshoot the problem but haven't been suc ...

Verify FileReader.onload function using Jasmine and AngularJS

I have a unique directive specifically designed for uploading and importing binary files. This directive listens for a change event on an <input type="file"../> element. Currently, I am facing an issue with the code coverage of my test. Although the ...

What advantages do binary shifts offer in enums?

What do you think about this code snippet? /** * Bitmask of states */ export const enum ViewState { FirstCheck = 1 << 0, // result is 1 ChecksEnabled = 1 << 1, // result is 2 Errored = 1 << 2, // result is 4 ...

Convert the list items into JSON format

<div class="col-xs-4 no-padding contenteditable-color" style="background-color: transparent;"> <ul class="ul-product"> <li class="li-product-page cars contenteditable" contenteditable="false">qweryt</li> </ul&g ...

What is the best way to smoothly scroll to another page using a specific id?

My website consists of multiple pages and I am looking for a code that will allow for smooth scrolling navigation to another page when loading on a specific id or section. For example, in the navbar I have multiple pages with links. When clicking on a lin ...

Using VueJs's createElement() to dynamically insert HTML content

I am currently working on a component that converts all icons to SVG format. By the end of my code, I have included the following: return createElement('i', '<SVG>CODE</SVG>' ) In the spot where the SPA ...

What could be causing the issue with my hour parameter in node-cron?

Having difficulty setting up a cron job to run with node-cron every Monday at 8:30. I've tried using "30 8 * * Mon" and even "30 08 * * Mon", but it doesn't seem to work. Interestingly, "30 * * * Mon" does work and runs every hour on the 30th min ...

Why do I keep encountering the error of an undefined variable? Where in my code am I making a mistake

I am struggling to troubleshoot an issue with creating a simple ease scroll effect using the jQuery plugins easing.js and jquery-1.11.0.min.js. $(function(){ //capturing all clicks $("a").click(function(){ // checking for # ...

The ExpressJS EJS issue arises when trying to access a property that is undefined

I'm new to NodeJS and seeking assistance. I am working on a website where users can promote their virtual conferences for others to see. I have set up a form with the POST method, where the data gets pushed into an array and then displayed in an EJS f ...

Oops! The function 'ModalDemoCtrl' has not been defined, causing an error

Hey there, I'm encountering an error when using angularJS in my project. The project is built on the django framework and does not include any additional JS files. Here are some snippets of my code: JavaScript: {{ ngapp }}.controller("ModalDemoCtrl" ...

Is it possible to reveal a concealed element or modify the functionality of a hyperlink?

I have a link in the navigation that includes an animated icon of a + turning into an x. When the icon is in the x state, I want users to be able to close it by clicking on the icon or text. However, I am unsure of the best way to approach this. One op ...

Discover how to initiate an ajax request from a tailored module when the page is loaded in ActiveCollab

When trying to initiate an AJAX call on the project brief page by adding a JavaScript file, I encountered some issues. My goal is to display additional information along with the existing project brief. I included a JavaScript file in a custom module and f ...

Steps for integrating a universal loader in Angular

My implementation of a global loader is as follows: In the CoreModule: router.events.pipe( filter(x => x instanceof NavigationStart) ).subscribe(() => loaderService.show()); router.events.pipe( filter(x => x instanceof NavigationEnd || x in ...

The embedded component is throwing an error stating that the EventEmitter is not defined in

Currently, I am delving into the realm of angular and facing an issue. The problem lies in emitting an event from a component nested within the main component. Despite my efforts, an error persists. Below is a snippet of my code: import { Component, OnIn ...

Adjusting the visibility of a div as you scroll

I'm trying to achieve a fade-in and fade-out effect on div elements when scrolling over them by adjusting their opacity. However, I'm facing difficulties in getting it to work properly. The issue lies in the fact that my div elements are positio ...

Issue: EISDIR error encountered while attempting to perform an operation on a directory. The error occurred specifically during the readlink process at 'D:study oobinjspages\_app.tsx' while executing the command 'npm run build' for a Next.js application

When attempting to run npm run build for my Next.js app in TypeScript, I encountered the error mentioned above. The issue seems to be related to the file _app.tsx being interpreted as a directory instead of a file. Here is the error screenshot along with t ...