GM's
GM's

Reputation: 133

How to do Proper SSR and Data Fetching in Next.js 14 App Router?

I recently transitioned from a page router to an app router due to its advanced features. However, I've encountered a dilemma and find myself perplexed regarding the implementation of SSR and data fetching.

The Problem:

The documentation suggests that, instead of using getServerSideProps() or similar methods, we can simply fetch data using the old fetch function with additional parameters like "{cache: 'no-store'}." However, I'm uncertain about how to create a universal helper function for fetching GraphQL data that can be used across all pages.

The Confusion:

Next.js advises against using hooks within components, as components are SSR by default. To utilize hooks, the recommendation is to include "use client" in the component. But, if we aim to fetch data as SSR and then store it in a hook, will the fetched data still maintain its SSR characteristics due to the use of "use client" within the component?

It would be better if you wrote a function to fetch data as SSR along with hooks to store data. Your assistance is greatly appreciated. Thank you in advance.

this is the helper function I was using across the app in the previous page router.

<pre>
export async function storefront(params) {
    const response = await  fetch(process.env.NEXT_PUBLIC_API_URL, { 
       method: "POST",
       headers: {
       "Content-Type": "application/json",
       "Another-Property": "Something here", },
       body: JSON.stringify({ params }),
     });
    return response.json();
   }
</pre>

Upvotes: 6

Views: 12864

Answers (1)

Darren Zou
Darren Zou

Reputation: 3744

Any data fetching that are called within "use client" directive will be fetched on the client side. All initial UI will be still rendered on the server, then hydrated on the client. So if you call the data fetching inside a hook, which will require you to be in a client component, the UI will still render on the server side as much as possible, but there will be no data, because data will be fetched once everything hits the client, and then rehydrated.

"But, if we aim to fetch data as SSR and then store it in a hook"

I don't think that is possible, as you cannot pass something like that to the client, you can, however, fetch data on the server and then pass it to the client. The "use client" directive doesn't mean client side rendering, it is still server side rendered.

The below code sample is completely server side rendered.

export async function Page() {
  const myDataQ = await fetch (....)
  const data = await myDataQ.json()
  return <ClientComp data={data}/>
}

#/ClientComp.tsx
"use client"
export const ClientComp = ({data}) => { 
  return <div> {data} </div>
}

Upvotes: 6

Related Questions