Search code examples
next.jsnext-authreact-server-components

nextjs 13 generateStaticParams used with next/header causes unhandled runtime error in dev mode


I am working on a new project, and recently used nextjs13 for my frontend application.

When using the function generateStaticParams with the next/header library function headers(),

I get an error in dev mode.

Unhandled Runtime Error - Dynamic server usage: headers

Screenshot of Error occured during dev mode

But when the frontend is on using next build / next start, the error does not appear.

The main reason I am using the next/header library is due to next-auth, to gain access to cookies.

generateStaticParams is in the app/detail/[questionId]/page.tsx file next/headers is in app/layout.tsx file

app/page.tsx

import React from "react";
import QuestionCard from "../components/Card/QuestionCard";
import Carousel from "../components/Carousel/Carousel";
import HomeNavBar from "../components/HomeNavBar/HomeNavBar";
import { ICarousel } from "../types/carousel";
import TabNavigator from "../components/TabNavigator/TabNavigator";

const getGoogleSession = async () => {};

const getQuestionList = async () => {
  const response = await fetch(`https://pioneroroom.com/questionlist`);
  const data = await response.json();
  return data;
};

const page = async ({ Question }: any) => {
  // const imageArr = await getCarouselImages();
  const data = await getQuestionList();

  return (
    <div className="main">
      <HomeNavBar />
      {/* <Carousel carousel={imageArr} /> */}
      <div className="contentbody">
        {data.data.map((e: any) => {
          return <QuestionCard key={e.questionId} question={e} />;
        })}
      </div>

      <TabNavigator activeLink={""} />
    </div>
  );
};

export default page;

app/layout.tsx

import { Roboto, Noto_Sans_KR } from '@next/font/google';
import NavBar from '../components/HomeNavBar/HomeNavBar';
import '../styles/globals.css';

import SessionContainer from '../components/Providers/SessionProvider';
import '../styles/globals.css';
import { unstable_getServerSession } from 'next-auth';
import { getSession } from '../utils/helper/session';
import { cookies, headers } from 'next/headers';
import HomeNavBar from '../components/HomeNavBar/HomeNavBar';
import TabNavigator from '../components/TabNavigator/TabNavigator';

const noto = Noto_Sans_KR({
    weight: '400',
    fallback: ['Roboto'],
    subsets: ['latin'],
});

const RootLayout = async ({ children }: any) => {
    const { segment } = children.props.childProp;
    const session = await getSession(headers().get('cookie') ?? '');
    const nextCookies = cookies();
    return (
        <html className={noto.className}>
            <head>
                <meta name="viewport" content="width=device-width,initial-scale=1" />
                <title>asdf</title>
            </head>
            <body>
                <SessionContainer session={session}>{children}</SessionContainer>
            </body>
        </html>
    );
};

export default RootLayout;

app/detail/[questionId]/page.tsx

import { headers } from 'next/headers';
import React, { use } from 'react';
import { getSession } from '../../../utils/helper/session';

const fetchPost = async (id: any) => {
    const res = await fetch(`https://pioneroroom.com/questionlist/${id}`);
    return await res.json().then((res) => res.data);
};

const DetailIdPage = async ({ params }: any) => {
    console.log('params.questionId', params.questionId);
    const post = await fetchPost(params.questionId);
    return (
        <div>
            <p>{JSON.stringify(post)}</p>
        </div>
    );
};

// BUG: generateStaticParams 함수가 현재 dev 모드에서 동작하지 않음.
// dynamic headers( next/headers )의 cookie등을 불러올 때 오류를 일으키고,
// dev mode에서 이 함수와 결합하여 사용하면 dynamic server usage: headers error 발생함.
/*
export async function generateStaticParams() {
    const res = await fetch('https://pioneroroom.com/questionlist');
    const data = await res.json();
    const arr = data.data.map((e: any) => {
        console.log('map', e.questionId);
        return {
            questionId: String(e.questionId),
        };
    });
    return arr;
}
*/

export default DetailIdPage;

Erasing either both of the code (generateStaticParams or next/header) solves the problem. No errors occuring in dev mode.


Solution

  • The workaround I'm using to stop these errors occurring is to turn fully turn off static rendering in dev mode. (but keeping it in prod)

    in the file that you're exporting generateStaticParams() from add this:

    // what used to be export function generateStaticParams
    function staticParams(){
    ...
    }
    
    // fix "dynamic server usage" errors in dev mode by turning off static generation and forcing dynamic rendering
    export const generateStaticParams =  process.env.NODE_ENV === "production" ? staticParams :  undefined;
    export const dynamic =  process.env.NODE_ENV === "production" ? 'auto' : 'force-dynamic';