[Nextjs] 라우트 세그먼트 옵션

김채운·2024년 12월 21일

Next.js

목록 보기
34/35

Next.js 앱에서 모든 페이지를 Static 페이지로 설정하여 풀 라우트 캐시를 최대한 활용하고자 할 때, 페이지를 구성하는 모든 컴포넌트들을 일일이 점검해야 한다. 동적 함수(searchParams, headers, cookies)를 사용하거나, 캐싱되지 않는 데이터 페칭을 수행하는 컴포넌트가 있다면, 해당 페이지는 자동으로 Dynamic 페이지로 설정되기 때문이다.

그러나 이러한 작업은 컴포넌트의 수가 많아질수록 복잡하고 시간이 많이 소요될 수 있다. 이를 해결하기 위해 Next.js는 특정 페이지의 동작을 강제로 Static 또는 Dynamic으로 설정하거나, Revalidate 타임을 강제로 지정할 수 있는 라우트 세그먼트 옵션(Route Segment Options)을 제공한다. 이번 포스트에서는 이 옵션을 살펴보고, 가장 자주 사용되는 dynamic 옵션을 중심으로 실습해 보도록 하겠다.


➡️ 라우트 세그먼트 옵션이란?

라우트 세그먼트 옵션은 특정 페이지의 동작을 강제적으로 설정할 수 있는 옵션이다. 이를 통해 캐싱 설정, Revalidate 타임, 서버 지역 등을 지정할 수 있다.

이전 포스트에서 book 페이지를 Static 페이지로 설정할 때 사용한 dynamicParams 옵션도 이러한 라우트 세그먼트 옵션의 하나이다.

  • dynamicParams: false: generateStaticParams에서 반환된 경로 외의 URL 요청은 모두 404 페이지로 리다이렉트.

  • dynamicParams: true (기본값): generateStaticParams 외의 경로도 실시간으로 생성.

이번에는 또 다른 라우트 세그먼트 옵션인 dynamic 옵션을 자세히 알아보도록 하자.


✨ dynamic 옵션 (페이지 유형 강제 설정)

dynamic 옵션은 특정 페이지를 강제로 Static 또는 Dynamic 페이지로 설정할 수 있다. 기본적으로 Next.js는 동적 함수 사용 여부나 캐싱 설정에 따라 페이지 유형을 자동으로 설정한다. 그러나 dynamic 옵션을 사용하면 이러한 기본 동작을 무시하고 강제로 페이지 유형을 지정할 수 있다.

dynamic 옵션의 값

  • auto: 기본값. 페이지를 구성하는 컴포넌트의 동작에 따라 Static 또는 Dynamic 페이지로 자동 설정.

  • force-dynamic: 페이지를 강제로 Dynamic 페이지로 설정.

  • force-static: 페이지를 강제로 Static 페이지로 설정.

  • error: 페이지를 강제로 Static 페이지로 설정하되, 동적 함수나 캐싱되지 않은 데이터 페칭이 있다면 빌드 오류 발생.


실습 (dynamic 옵션 사용)

1️⃣ 기본값인 auto

아래와 같이 dynamic 옵션을 auto로 설정하면, 페이지는 기본 원칙에 따라 유형이 자동으로 설정된다.

export const dynamic = "auto"; // 기본값 (생략 가능)

export default async function Page({ searchParams }) {
  const data = await fetch(`${process.env.API_URL}/data?q=${searchParams.q}`);
  return <div>{data}</div>;
}

동작 원칙

  • 동적 함수를 사용하거나 캐싱되지 않은 데이터 페칭(cache: "no-store")을 하면 Dynamic 페이지로 설정.

  • 그렇지 않다면 Static 페이지로 설정.


2️⃣ force-dynamic (무조건 Dynamic 페이지)

아래와 같이 dynamic 옵션을 force-dynamic으로 설정하면, 페이지 내부의 모든 동작에 관계없이 무조건 Dynamic 페이지로 설정된다.

export const dynamic = "force-dynamic";

export default async function Page({ searchParams }) {
  const data = await fetch(`${process.env.API_URL}/data?q=${searchParams.q}`);
  return <div>{data}</div>;
}

동작 원칙

  • 동적 함수나 데이터 캐싱 설정 여부와 관계없이 실시간으로 데이터를 불러오며 페이지를 렌더링.

  • 모든 요청마다 새롭게 페이지 생성.


3️⃣ force-static (무조건 Static 페이지)

아래와 같이 dynamic 옵션을 force-static으로 설정하면, 페이지 내부에서 어떠한 동적 함수를 사용했건 어떤 데이터 페칭을 사용했던 간에 무조건 강제적으로 다 static페이지로서 작동하게 설정된다.

export const dynamic = "force-static";

export default async function Page({ searchParams }) {
  const data = await fetch(`${process.env.API_URL}/data?q=${searchParams.q}`);
  return <div>{data}</div>;
}

동작 원칙

  • 쿼리스트링 같은 동적 함수(searchParams)는 undefined로 처리.

  • cache: "no-store"가 설정된 데이터 페칭은 자동으로 force-cache로 변경.

이처럼 dynamic라우트 세그먼트 옵션의 값을 force-static으로 설정하게 되면 무조건 static페이지로서 작동하도록 알아서 다 변경이 된다.

⚠️ 주의

  • force-static을 사용할 때, 검색어 기반으로 데이터를 불러오는 search 페이지와 같은 경우에는 검색 기능이 동작하지 않을 수 있다.

4️⃣ error (Static 페이지 설정 오류 발생)

아래와 같이 dynamic 옵션을 error로 설정하면, force-static과 동일하게 페이지를 강제로 static페이지로 설정할 수 있는데 만약 페이지를 Static으로 설정할 수 없는 이유(캐싱되지 않는 데이터 페칭, 동적 함수 사용 등)가 있다면 빌드 오류를 발생시킨다.

export const dynamic = "error";

export default async function Page({ searchParams }) {
  const data = await fetch(`${process.env.API_URL}/data?q=${searchParams.q}`);
  return <div>{data}</div>;
}

빌드 오류 메시지

Error occurred prerendering page "/search": Route "/search" with dynamic="error" couldn't be rendered statically because it used searchParams.q.

이 오류 내용을 살펴보면, search페이지를 렌더링 하다가 오류가 발생했는데 이유는, dynamic 옵션이 error로 설정된 현재의 search페이지는 static페이지로서 렌더링이될 수 없기 때문이다. 왜냐, searchParams라는 쿼리스트링 값을 불러오는 동적 함수를 사용하고 있기 때문이다. 라고 static페이지로 변경할 수 없는 이유를 알려준다.

이 옵션은 Static 페이지로 강제 설정할 수 없는 페이지를 사전에 확인하고 수정할 때 유용하다. 그래서 force-static보다는 버그가 발생할 가능성이 낮은 옵션이다.


⚠️ 주의사항

dynamic 옵션은 특정 상황에서는 유용할 수 있지만, 남용은 권장되지 않는다.

1. Next.js의 기본 동작 무시

앱 라우터에서는 페이지를 구성하는 모든 컴포넌트를 기준으로 Static/Dynamic을 자동으로 설정하는 강력한 메커니즘을 제공한다. 이를 무시하면 search페이지 처럼 의도치 않은 부작용이 발생할 수 있다.

2. 실험적 사용

그럼에도 이런 옵션을 알아두면, 개발할 때 페이지의 캐싱을 실험해 보거나 무조건 static 또는 무조건 dynamic으로 설정이 되어야 하는 페이지처럼 강제로 특정 동작을 설정해야 하는 임시 상황에서 일단 빠르게 이런 라우트 세그먼트 옵션을 적용한 다음 나중에 천천히 고쳐나가는 방식으로 개발을 진행한다던지 등의 편의성을 누릴 수 있다. 그래서 알고는 있되 꼭 필요한 경우에만 사용하는 걸 권장한다 정도로 받아들이면 된다.

0개의 댓글