[Next.js] 동적 라우팅과 fallback 옵션

js43o·2023년 1월 28일
0
post-custom-banner

문제 상황

동적 라우팅 페이지에서 getStaticPathsgetStaticProps를 통해 Static Generation을 적용하려는 상황에서, 다음과 같은 문제가 발생하였다.

  • Link 컴포넌트를 통해 동적 라우팅 페이지로 접근할 때에는 getStaticProps가 정상적으로 호출됨.
  • 그러나 해당 페이지에서 새로고침을 하거나, 임의의 페이지에서 직접 URL을 변경하여 이동하는 경우 getStaticProps가 호출되지 않음.

내 코드의 경우 getStaticProps에서 비동기 함수를 통해 외부 데이터를 불러와 페이지 컴포넌트로 넘겨주고 있으며, getStaticPaths에서 빌드 시 미리 생성할 페이지 경로(path)를 따로 주진 않았다.

fallbacktrue이므로 미리 생성되지 않은 페이지여도 요청 시점에 동적으로 잘 생성될 것이라 생각했는데, getStaticProps가 호출되지 않아 페이지 렌더링에 필요한 데이터를 받지 못해 에러가 발생한 모습이다.

예상치 못한 현상이 일어나서 조금 당황스러웠다.

임시 해결법 1.

처음엔 이렇게 getStaticPaths모든 동적 페이지 경로를 포함하여 빌드 시 모든 페이지를 미리 생성하도록 하였다. 다만 이 방법의 경우 개발 모드에서 매 요청마다 전체 DB 쿼리가 호출되므로 속도가 상당히 느려진다는 단점이 있었다.

임시 해결법 2.

Static Generation을 포기하고 대신 이렇게 getServerSideProps을 사용하면 매 요청마다 해당 함수가 정상적으로 호출되었고 페이지 렌더링 문제 또한 해결되었다. 속도 측면에서도 위 방법보다 훨씬 빨랐다.

그리고 원인?

처음엔 Link 컴포넌트를 통해 접근하는 것과 URL을 통해 직접 페이지를 요청하는 것이 내부적으로 다르게 동작하는 것으로 추측했다. 하지만 원인은 따로 있었고 결과적으로 에러가 아닌 정상적으로 동작하는 상황이었다.

사실 getStaticProps가 호출되지 않는 것이 아니라 뒤늦게 호출되는 것이었다.

Next.js 공식 문서getStaticPaths 부분에는 fallback에 대한 다음 설명이 존재한다.

만약 fallbacktrue이면, 빌드 시간에 만들어지지 않은 페이지를 요청해도 404 페이지를 응답하지 않는다.
대신, 첫 요청에 대해서는 fallback 버전의 페이지를 응답하고, 백그라운드에서 요청받은 경로에 따른 HTML 및 JSON을 정적으로 생성한다. 여기에는 getStaticProps를 호출하는 것 또한 포함된다.

나는 getStaticProps가 어떤 상황에서도 페이지 생성 전 반드시 호출되는 줄 알았기에, 이를 통해 받는 데이터가 존재하지 않을 경우의 분기 처리를 따로 하지 않았다. 그렇기에 렌더링에서 에러가 발생하는 것이었다. (fallback 페이지에 대한 개념도 느슨하게 생각하고 있었다)

fallback == true를 페이지 요청 시에 동적으로 생성하도록 해주는 옵션 정도로만 알고 있었는데, 생각보다 중요한 절차가 있었다. 버그가 아니여서 다행이지만, 앞으로 이런 일이 있을 때마다 가장 먼저 공식 문서를 꼼꼼히 읽어봐야겠다...

profile
공부용 블로그
post-custom-banner

0개의 댓글