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

The margin persists despite the usage of the * selector and !important declaration

I'm currently working on a website built upon this template: https://github.com/issaafalkattan/React-Landing-Page-Template My issue arises when trying to remove margins in multiple sections. For instance, I want to eliminate the 'orange' ar ...

Trouble with JavaScript preventing the opening of a new webpage

I need help with a JavaScript function to navigate to a different page once the submit button is clicked. I have tried using the location.href method in my code, but it's not working as expected. Even though I am getting the alert messages, the page i ...

Enhance the functionality of the kendo grid by incorporating additional buttons or links that appear when the

Is there a method to incorporate links or buttons when hovering over a row in a kendo grid? I've searched through the documentation and looked online, but haven't found a solution. I'm considering if I should modify my row template to displa ...

"The interplay of Vue components: exploring the relationships, lifecycle hooks

Brand new to utilizing Vue.js. I am exploring the concept of having a single parent component and two child components that need to communicate asynchronously through Vue's event bus system. This involves using a dummy Vue object as a shared container ...

"Empty array conundrum in Node.js: A query on asynchronous data

I need assistance with making multiple API calls and adding the results to an array before returning it. The issue I am facing is that the result array is empty, likely due to the async nature of the function. Any help or suggestions would be greatly appre ...

Begin a SeleniumWebDriver session after Google Chrome has been launched beforehand

I am looking to create an automation using SeleniumWebDriver and Node.js, but I am facing an issue where I cannot start the automation if Google Chrome is already open and in use by the user. Currently, my workaround is to close all instances of Chrome be ...

Creating a chart with multiple series in canvas js through looping

I'm currently working on creating a multi-series chart using Canvasjs. I've encountered an issue where I can't include a loop inside the dataPoints and have had to manually code everything. Is there a way to utilize for loops in this scenari ...

Adjust the position of a textarea on an image using a slider

Currently, I am exploring how to creatively position a textarea on an image. The idea is to overlay the text on the image within the textarea and then use a slider to adjust the vertical position of the text as a percentage of the image height. For instanc ...

Is there a way to automatically update the state in ReactJS whenever new information is added or deleted, without the need to manually refresh the page

I have encountered an issue that I have been trying to resolve on my own without success. It seems that the problem lies in not updating the Lists New state after pushing or deleting from the API. How can I rectify this so that manual page refreshing is no ...

The success callback in the first call will only be triggered when a breakpoint is established

I currently have an ASP.NET MVC webpage with Bootstrap and several plugins integrated. I am attempting to implement a confirmation message using the Bootbox plugin before deleting a record, followed by reloading the page upon successful deletion. Everythi ...

Flexible array for varying results

I'm attempting to display a random selection from two arrays by alternating between them, with no concern for storage capacity. Unfortunately, my code is not functioning correctly and I am unsure why. var male = ["have a shot", "item 2", "item 3"]; ...

Determine whether it is SSR or not

I have developed a versatile package designed for compatibility with both CRA and NextJS environments. Within this package, there is a crucial component that configures attributes on body, html, and title tags. To achieve this functionality, I initially ...

Error occurs when using Express.js in combination with linting

https://www.youtube.com/watch?v=Fa4cRMaTDUI I am currently following a tutorial and attempting to replicate everything the author is doing. At 19:00 into the video, he sets up a project using vue.js and express.js. He begins by creating a folder named &apo ...

How can you prevent JQuery AJAX from automatically redirecting after a successful form submission?

Encountered an issue with loading http://example.com/signup.ashx: The redirect from 'http://example.com/signup.ashx' to '' was blocked by the CORS policy. This is due to the absence of 'Access-Control-Allow-Origin' header on t ...

Accessing a jstl variable within javascript script

I need to access a JSTL variable within a JavaScript function. The JavaScript code submits a form. $("#userSubmit").on('submit', function () { document.getElementById("userForm").submit(); }); In the server-side code - request.setAttribu ...

Avoiding the use of if statements in Javascript

I've recently started learning Javascript and I'm facing an issue with my code. I want to create a functionality where clicking on an image on one page redirects you to another page and shows a specific div based on the clicked image. To achieve ...

EJS functionality is operational, however, the HTML content is not displaying

I'm currently developing a timer using Express.js and EJS. My goal is to update the HTML dynamically, but I seem to be encountering an issue where nothing gets displayed. Strangely enough, I can see the output in my CLI with console.log. <div id ...

What advantages can be gained by opting for more precise module imports?

As an illustration, consider a scenario where I have an Angular 6 application and need to bring in MatIconModule from the @angular/material library. Two options could be: import { MatIconModule } from '@angular/material/icon'; Or import { Mat ...

Remove a field from a JSON array

Consider the following JSON array: var arr = [ {ID: "1", Title: "T1", Name: "N1"}, {ID: "2", Title: "T2", Name: "N2"}, {ID: "3", Title: "T3", Name: "N3"} ] Is there a way to remove the Title key from all rows simultaneously without using a loop? The r ...

Assign value to twig variable using JavaScript in Symfony version 3.4

Hello everyone, I am currently working on a form that is functioning well. However, I am facing an issue with setting the localization of a place manually using latitude and longitude values. To address this, I decided to create a map with a draggable mark ...