deroccha
deroccha

Reputation: 1183

How to Avoid Duplicate GraphQL Queries in Next.js with Server-Side Rendering?

I'm working on a Next.js project and have a page that requires fetching data from a GraphQL API. The problem is that I'm making the same GraphQL query twice: once to generate metadata and once to render the page content. This redundancy is causing unnecessary overhead.

Here's my current setup:

import DynamicZoneRenderer from '@/components/dynamic-zone-renderer';
import { logger } from '@/lib/logger/pino';
import { getPathSegment } from '@/lib/utils';
import { notFound } from 'next/navigation';
import { componentMap } from '@/config/component-mapper';
import { PageQueryFields } from '@/types/page';
import { getPageByFieldValue } from '@/graphql/service/page.service';
import { PageByPathDocument } from '@/graphql/queries/page.generated';
import { type Page } from '@/graphql/types.generated';
import { Metadata } from 'next';

async function fetchPageData(): Promise<Page | null> {
  const path = getPathSegment();
  const data: Page | null = await getPageByFieldValue(
    PageQueryFields.Path,
    path,
    PageByPathDocument
  );
  return data;
}

export const generateMetadata = async (): Promise<Metadata> => {
  const data = await fetchPageData();
  return {
    title: data?.title,
    description: data?.metas?.metaDescription
  };
};


export default async function RenderPage(pageData: Page) {
  try {
    const data = await fetchPageData();
    const { components } = data || {};

    if (!pageData) {
      throw new Error('NEXT_NOT_FOUND');
    }
  
    return (
      <>

        <main className="flex min-h-screen flex-col items-center ">
          <div>
            <h1>{data?.title}</h1>
          </div>
          {components && (
            <DynamicZoneRenderer
              components={components}
              componentMap={componentMap}
            />
          )}
        </main>
      </>
    );
  } catch (error: any) {
    if (error.message === 'NEXT_NOT_FOUND') {
      notFound();
    } else {
      logger.error(error);
      throw error;
    }
  }
}

I need to ensure that the GraphQL query is executed only once while still being able to:

Generate metadata for the page. Render the page content based on the fetched data.

what are my choices using NextJS 15-rc

Upvotes: 0

Views: 47

Answers (0)

Related Questions