Routing

시연·2024년 5월 6일
1
post-thumbnail

✅ 간단한 용어

  • Tree : 계층 구조를 시각화하기 위한 규칙 (예를 들어 부모 자식 구성요소가 있는 구성요소를 나타내거나 폴더 구조 등을 트리로 나타냄)
  • Subtree : tree의 일부로, root 에서 시작하여 leaf들에서 끝남
  • Root : root 레이아웃과 같은 tree 또는 하위 tree의 첫 번째 노드
  • Leaf : URL 경로의 마지막 세그먼트와 같이 자식이 없는 tree의 노드

  • URL Segment : 슬래시로 구분된 URL 경로의 일부
  • URL Path : 도메인 뒤에 오는 URL의 일부(세그먼트로 구성됨)

APP 라우터

버전 13이 나오면서 APP Router가 등장했다!!

변화된 점

  • app 폴더가 page 폴더를 대체할 수 있게 됬다.
  • app directory내부에서는 모든 컴포넌트가 기본적으로 서버컴포넌트로 동작한다.
    • app directory 내부에서 클라이언트 컴포넌트를 사용하고 싶다면 파일 최상단에 use client를 써주면 된다.

폴더 및 파일의 역할

next.js는 폴더가 경로를 정의하는 데 사용되는 파일 시스템 기반 라우터를 사용

  • 폴더는 경로를 정의하는데 사용한다.
  • 파일은 경로 세그먼트에 대해 표시되는 UI를 만드는데 사용한다.

Route Segments

경로의 각 폴더는 URL 주소를 구성하는 부분을 나타냅니다.
매 경로 세그먼트는 실제 URL 주소의 한 부분을 의미합니다.
간단히 말하면, Route Segments는 URL 주소를 슬래시('/')로 나눈 각 부분을 말합니다.


Nested Routes

중첩 라우팅(Nested Routing)이란 라우팅 맵핑을 최상위 컴포넌트 뿐만 아니라 여러 개의 컴포넌트에 걸쳐서 단계별로 정의하는 라우팅 기법이다.
간단히 말하면, 페이지 안에 또 다른 페이지가 들어가는 것을 말한다.

일반적으로 웹 사이트는 여러 페이지로 이루어져 있는데, 중첩 라우팅은 한 페이지 안에 또 다른 작은 페이지를 넣는 것이다. 이 작은 페이지들은 그들만의 주소를 가지고 있고, 사용자는 이를 통해 메인 페이지에서도 서브 페이지로 바로 이동할 수 있다.

이점

  • 사용자 경험이 더 향상되고, 앱이 더 유기적으로 동작할 수 있습니다.
  • 중첩된 구조를 통해 웹 애플리케이션의 복잡도를 관리하고 세분화된 기능을 구현할 수 있다.

File Conventions (파일 규칙)

이를 통해 프로젝트를 조직화하고 유지 관리하기가 훨씬 쉬워진다.

  • layout : 세그먼트 및 세그멘트 하위에 대한 공유 UI
  • page : 경로의 고유한 UI 및 공개적으로 접근 가능한 경로 만들기
  • loading : 세그먼트와 해당 자식들이 로딩 중일때 보여지는 UI
  • not-found : 세그먼트와 해당 자식들을 찾지 못했을때 보여지는 UI
  • error : 세그먼트와 해당 자식들이 오류가 났을때 보여지는 UI (error.js는 무조건 클라이언트 컴포넌트여야함)
  • global-error : 전역 오류 UI
  • route : 서버측 API 끝점 (Server-side API endpoint)
  • template : 재 렌더링될때 보이는 UI
  • default : 병렬 라우트에 대한 대체 UI

Component Hierarchy (구성 요소 계층)

경로 세그먼트의 특수 파일에 정의된 React 구성 요소는 특정 계층 구조로 렌더링된다.
이는 말 그대로, 페이지 구성 요소들이 폴더 구조와 같은 계층 구조를 형성하여 렌더링됨을 의미한다.
중첩된 경로에서 세그먼트의 구성요소는 상위 세그먼트의 구성요소 내에 포함된다.

간단히 말해, 한 페이지 안에 다른 페이지가 들어갈 수 있는데, 이때 각 페이지의 구성 요소들은 계층적으로 조직되어 렌더링된다..


Colocation

  • 자주 함께 변경되는 파일들을 한 곳에 모아두는 방식이다.
    page.js또는 route.js 공개적으로 주소를 지정할 수 있다.


위의 이미지를 보면, components, styles, tests 등의 폴더들이 모두 같은 app 폴더 내에 위치하고 있다.

이점

  • 이러한 구조는 프로젝트를 조직화하고 유지 관리하기 쉽게 만들어준다.


Advanced Routing Patterns (고급 라우팅 패턴)

앱 라우터는 더 복잡한 라우팅 구조를 만들기 위한 방법을 제공한다. 아래와 같다

  • 병렬 라우트(Parallel Routes) : 동일한 화면에서 두 개 이상의 페이지를 동시에 표시한다.
  • 가로채기 라우트(Intercepting Routes) : 현재 페이지의 경로를 가로채어 다른 경로의 컨텍스트에 표시한다. 현재 페이지의 컨텍스트를 유지하는 것이 중요할 때 사용할 수 있다.

이러한 패턴을 통해 더 풍부하고 복잡한 UI를 구축할 수 있고, 소규모 팀과 개별 개발자가 구현하기에는 어려웠던 기능을 더욱 쉽게 사용할 수 있게 됨.

병렬 라우팅(Parallel Routes)

  • 여러 경로를 동시에 또는 조건부에 따라 랜더링할 수 있게 한다. ( 대시보드 및 소셜 사이트 피드와 같이 앱의 매우 동적인 섹션에 유용하다.)


병렬 경로를 사용하면 teamanalytics페이지를 동시에 랜더링할 수 있다.


이렇게 병렬 경로를 설정하면 각 경로에 대해 독립적인 에러 및 로드 상태를 정의할 수 있다.


슬롯

  • 병렬 라우트는 명명된 슬롯(named slots)을 사용하여 생성됩니다.
  • 병렬 라우팅은 인증 상태와 같은 특정 조건에 따라 슬롯을 조건부로 렌더링할 수 있도록 해준다. 이를 통해 동일한 URL에서 완전히 분리된 코드를 사용할 수 있게 된다.
  • 슬롯은 @folder 컨벤션으로 정의되며, 같은 수준의 레이아웃으로 props로 전달됩니다.
  • 슬롯은 경로 세그먼트가 아니며 URL 구조에 영향을 주지 않습니다. /@team/members 파일 경로는 /members에서 액세스할 수 있습니다.

    예 ) 다음 파일 구조는 @analytics 및 @team이라는 두 개의 명시적 슬롯을 정의한다.

활성 상태 및 탐색

기본적으로 next.js는 각 슬롯의 활성 상태(또는 하위 페이지)를 추적한다.
그러나 슬롯 내에서 랜더링되는 콘텐츠는 탐색 유형에 따라 달라진다.

Soft Navigation

탐색 시 Next.js는 현재 URL과 일치하지 않더라도 슬롯의 이전 활성 상태를 렌더링한다.

Hard Navigation

전체 페이지 재렌더링이 필요한 Hard Navigation에서 Next.js는 먼저 일치하지 않는 슬롯의 default.js 파일을 렌더링하려고 시도한다. 사용할 수 없는 경우 404가 렌더링된다.

Unmatched Routes (비교할 수 없는 경로)

  • 기본적으로 슬롯 내에서 렌더링되는 컨텐츠는 현재 URL과 일치한다.
  • 일치하지 않는 슬롯의 경우, 콘텐츠는 Next.js가 렌더링하는 라우팅 기술 및 폴더 구조에 따라 다르다.

default.js

  • 현재 URL을 기반으로 슬롯의 활성 상태를 복구할 수 없을 때 Next.js가 대체로 렌더링할 default.js 파일을 정의할 수 있다.
    @team 슬롯에는 settings 디렉토리가 있지만 @analytics에는 없다.

    루트(/)에서 /settings로 이동한다면, 렌더링되는 컨텐츠는 네비게이션의 유형과 default.js 파일의 유무에 따라 다를 수 있습니다.

Conditional Routes (조건부 라우트)

  • 병렬 라우트는 조건부 라우팅을 구현하는 데 사용할 수 있다. 예를 들어 인증 상태에 따라 @dashboard 또는 @login 라우트를 렌더링할 수 있다.
/* app/layout.tsx */

import { getUser } from '@/lib/auth'
 
export default function Layout({ params, dashboard, login }) {
  const isLoggedIn = getUser()
  return isLoggedIn ? dashboard : login
}

Intercepting Routes(라우트 가로채기)

  • 라우트 가로채기는 현재 레이아웃 안에서 라우트를 로드하면서 현재 페이지의 컨텍스트를 유지할 수 있게 해준다. 이러한 라우팅 패러다임은 특정 경로를 "가로채서" 다른 경로를 표시하고 싶을 때 유용하다.

Convention

라우트 가로채기는 (..) 구문을 사용하여 정의할 수 있다. 이는 상대 경로 표기법인 ../과 유사하지만 세그먼트에 대해 적용된다.

  • (.)는 동일한 수준의 세그먼트와 일치합니다.
  • (..)는 한 수준 위의 세그먼트와 일치합니다.
  • (..)(..)는 두 수준 위의 세그먼트와 일치합니다.
  • (...)는 루트 앱 디렉토리부터의 세그먼트와 일치합니다.

    예를 들어, (..)photo 디렉토리를 생성함으로써 피드 세그먼트 내부에서 사진 세그먼트를 가로챌 수 있다.


Creating Routes

각 폴더는 URL의 한 세그먼트에 해당하는 route segment(경로 세그먼트)를 나타낸다. 중첩된 경로를 만들기 위해서는 폴더를 서로 중첩시킬 수 있다.

특별한 page.js파일을 사용하여 경로 세그먼트를 공개적으로 엑세스할 수 있다.

위 예에서는 /dashboard/analytics URL 경로에 해당하는 경로가 없으므로 공개적으로 액세스 할 수 없다.
이 폴더는 구성 요소, 스타일시트, 이미지 또는 다른 공동 위치 파일을 저장하는 데 사용할 수 있다.

이점

  • 이렇게 구성된 라우트 시스템을 통해 원하는 URL 경로와 그에 따른 폴더 구조를 간편하게 정의하고 사용할 수 있다.


Creating UI (UI 생성중)

각 경로 세그먼트에 대한 UI를 만들 때는 특정한 파일 규칙을 따른다. 가장 일반적인 방법은 페이지별로 UI를 표시하는 page.js 파일과 여러 경로에 걸쳐 공유되는 UI를 표시하는 layout.js 파일을 사용하는 것이다.

예를 들어, 첫 번째 페이지를 생성하려면 app 디렉토리 내부에 page.js 파일을 추가하고 그 안에 React 컴포넌트를 정의하여 내보낸다.

  //app/page.tsx
   
  export default function Page(){
   return <h1>Hello, Next.js!</h1>
  }

pages

앱 라우터는 page.js, layout.js, 그리고 template.js 파일을 생성할 수 있도록 새로운 파일 규칙을 도입했습니다.

페이지 (pages)
페이지는 라우트에 고유한 UI를 정의합니다. 중첩된 폴더를 사용하여 라우트를 구성하고, 각 라우트에 대해 page.js 파일을 사용하여 해당 UI를 정의합니다.

레이아웃 (layouts)
레이아웃은 여러 페이지에서 공유되는 UI를 정의합니다. 페이지를 전환할 때 레이아웃은 상태를 유지하고 상호작용을 보존하여 다시 렌더링되지 않습니다. 레이아웃은 중첩이 가능합니다.

layout.js 파일에서는 React 컴포넌트를 default로 내보내어 레이아웃을 정의한다.
이 컴포넌트는 랜더링 중에 자식 레이아웃이나 페이지로 채워질 children prop를 받아야 한다.

 export default function DashBoardLayout({
  	children,
 }: {
  return (
  	<section>
      {/* 공유 UI를 여기에 포함(헤더 또는 사이드바)*/}
      <nav></nav>
      
      {children}
    </section>
  );
}

이렇게 구성된 파일 시스템을 통해 각 페이지와 레이아웃을 간편하게 정의하고 사용할 수 있습니다.

Root Layout (Required)

Root Layout은 app 디렉터리 최상위에서 정의되며 모든 라우트에 적용된다.
이 레이아웃을 사용하면 서버에서 반환된 초기 HTML을 수정할 수 있다.

  • app 디렉터리에는 반드시 루트 레이아웃이 포함되어야 한다.
  • 루트 레이아웃은 <html><body> 태그를 반드시 정의해야 한다. (next.js는 이를 자동으로 생성해주지 않음)
  • 루트 레이아웃은 기본적으로 서버 컴포넌트이며 클라이언트 컴포넌트로 설정할 수 없다.
export default function RootLayout({
  children,
}: {
  return (
  	<html lang="en">
      <body>{children}</body>
    </html>
  )
}

이렇게 최상위 레이아웃을 설정하면 모든 페이지에 일관된 레이아웃을 적용할 수 있다.

Nesting Layouts(중첩 레이아웃)

특정 경로 세그먼트가 활성화될 때, 해당 세그먼트에 매칭되는 폴더 내에 정의된 레이아웃이 적용된다.
이를 중첩 레이아웃이라고 합니다.

예를 들어, app/dashboard/layout.js와 같이 정의된 레이아웃은 대시보드 페이지에서 사용된다.

파일 구조의 기본 동작에 따라, 레이아웃은 자식 레이아웃을 갖고 있으며 이를 children 속성으로 감싸게 된다.

위의 두 레이아웃을 결합하려면 루트 레이아웃 (app/layout.js)이 대시보드 레이아웃 (app/dashboard/layout.js)을 둘러싸고, 대시보드 레이아웃은 app/dashboard/*내부의 경로 세그먼트를 둘러싸게 된다.

Route Groups를 사용하면 공유 레이아웃에서 특정 경로 세그먼트를 선택적으로 포함하거나 제외할 수 있습니다.

Route Groups

일반적으로 app 디렉토리의 중첩된 폴더는 URL 경로와 일치한다.
그러나 이러한 폴더를 라우트 그룹으로 표시하여 해당 폴더가 URL 경로에 포함되지 않도록 할 수 있다.
이는 라우트 세그먼트와 프로젝트 파일을 논리적으로 구성하는 데 유용한다.

Route Group이 유용하게 사용되는 경우

1. 사이트 섹션, 의도 또는 팀별로 경로를 구성할 때

2. 동일한 라우트 세그먼트 수준에서 중첩된 레이아웃을 활성화할 때

  • 여러 루트 레이아웃을 포함하여 동일한 세그먼트에 여러 중첩 레이아웃 만들기
  • 특정 세그먼트를 레이아웃으로 선택 할 때

Convention

폴더 이름을 괄호로 묶음으로써 생성할 수 있다.

Examples

URL 경로에 영향을 주지 않고 라우트를 구성한다.
각 그룹의 폴더는 URL에서 생략됩니다. (예 : (marketing) 또는 (shop))

(marketing) 및 (shop) 내부의 경로가 동일한 URL 계층 구조를 공유하더라도 폴더 내에 layout.js 파일을 추가하여 각 그룹에 대해 다른 레이아웃을 생성할 수 있다.

특정 세그먼트의 레이아웃을 선택하는 방법

특정 라우트를 레이아웃으로 선택하려면 새 라우트 그룹(예 : (shop))을 만들고 동일한 레이아웃을 공유하는 라우트를 그룹(예 : account and cart)으로 이동한다. 그룹 외부의 라우트는 레이아웃을 공유하지 않는다. (예 : checkout)

다중 루트 레이아웃 만들기

여러 루트 레이아웃을 만드려면 최상위 layout.js 파일을 제거하고 각 경로 그룹 내에 layout.js파일을 추가한다.
이것은 완전히 다른 UI/UX를 가진 섹션으로 애플리케이션을 분할하는데 유용하다.

및 태그는 각 루트 레이아웃에 추가해야 한다.



Templates

templates는 각 자식 레이아웃 또는 페이지를 둘러싸는 레이아웃과 유사하다.
레이아웃은 경로 간에 지속되고 상태를 유지하는 반면, 템플릿은 탐색 시마다 자식의 새로운 인스턴스를 생성한다.
이는 템플릿을 공유하는 라우트 간에 이동할 때, 컴포넌트의 새 인스턴스가 마운트되고 DOM 요소가 다시 생성되며 상태가 유지되지 않으며 효과가 동기화된다는 것을 의미한다.

특정 동작이 필요한 경우 레이아웃보다 템플릿이 더 적합한 옵션일 수 있다.

  • CSS 또는 애니메이션 라이브러리를 사용한 진입/이탈 애니메이션
  • useEffect를 사용하는 기능 및 useState를 사용하는 기능
  • 기본 프레임워크 동작 변경. 예를 들어, 레이아웃 내의 Suspense 경계는 페이지 전환 시에만 대체 콘텐츠를 보여주지만 템플릿의 경우 매번 탐색할 때마다 대체 콘텐츠가 표시된다.

특별한 이유가 없는 경우 한 레이아웃을 사용하는 것이 좋다.


Dynamic Routes(동적 라우트)

동적 라우트는 정확한 세그먼트 이름을 미리 알 수 없는 경우에 사용된다.
이는 주로 동적 데이터를 다룰 때 유용하다.
동적 라우트는 요청 시간에 채워지거나 빌드 시간에 미리 렌더링되는 세그먼트를 가진다.

규칙

  • 대괄호로 폴더 이름을 감싸면 생성된다.
  • Dynamic Segments는 params prop으로 layout, page, routegenerateMetadata 함수에 전달된다.


블로그를 만든다고 가정했을때 다음과 같은 라우트 app/blog/[slug]/page.js를 포함할 수 있으며,
여기서 [slug]는 블로그 게시물의 동적 세그먼트이다.

// app/blog/[slug]/page.tsx
export default function Page({ params }: { params: { slug: string } }) {
  return <div>My Post: {params.slug}</div>;
}

Generating Static Params (정적 매개변수 생성)

  • 정적 매개변수는 generateStaticParams 함수를 사용하여 생성할 수 있습니다. 이를 통해 빌드 시간에 정적으로 라우트를 생성할 수 있다.

Catch-all 세그먼트

  • Catch-all 세그먼트를 사용하면 연속된 세그먼트를 일치시킬 수 있다. 이는 동적으로 변하는 URL 경로를 처리할 때 유용하다.

Optional Catch-all 세그먼트

  • Optional Catch-all 세그먼트를 사용하여 세그먼트를 선택적으로 만들 수 있다.
    catch-all과 optional catch-all 세그먼트의 차이점은 optional의 경우 매개변수 없이 라우트도 일치한다는 것이다.




Loading UI and Streaming

Loading UI

  • loading.js를 사용하면 React Suspense와 함께 의미 있는 로딩 UI를 생성할 수 있다. 이는 서버에서 라우트 세그먼트의 내용이 로드되는 동안 대기하는 동안 사용자에게 대체 UI를 제공하는 데 도움이 된다.

Instant Loading States (즉시 로딩 상태)

  • Navigation 시 즉시 표시되는 대체 UI이다.
  • 로딩 인디케이터(스켈레톤 또는 스피너) 또는 향후 화면의 일부인 커버 사진, 제목 등을 미리 랜더링 할 수 있다.
  • 폴더 내에 loading.js파일을 추가하여 생성한다.

Streaming

React와 Next.js에서 스트리밍이 작동하는 방식을 이해하기 위해서는 서버 측 렌더링(SSR)과 그 제한 사항을 이해하는 것이 도움이 된다.

Suspense 스트리밍

  • React와 Next.js에서 사용되는 작업 방식이다.
  • 서버는 모든 데이터를 가져온 후에만 페이지의 HTML을 랜더링할 수 있다.
  • 페이지의 HTML을 작은 클럭으로 분할하여 서버에서 클라이언트로 점진적으로 전송할 수 있게한다.
  • React의 컴포넌트 모델과 잘 작동한다. (각 컴포넌트는 클럭으로 간주될 수 있다.)
  • 우선순위가 높은 컴포넌트(예: 제품 정보)나 데이터에 의존하지 않는 컴포넌트(예: 레이아웃)를 먼저 보낼 수 있으며 React는 조기에 Hydration을 시작할 수 있다. 우선순위가 낮은 컴포넌트(예: 리뷰, 관련 제품)는 해당 데이터가 검색된 후에 동일한 서버 요청에 보낼 수 있다.
  • 스트리밍은 긴 데이터 요청이 페이지 렌더링을 차단하는 것을 방지하고 Time To First Byte (TTFB)와 First Contentful Paint (FCP)를 줄일 수 있어 특히 유용하다. 또한 느린 기기에서 Time to Interactive (TTI)를 개선하는 데 도움이 된다.
  • TTFB(Time to First Byte)는 HTTP 요청을 했을때 처음 byte (정보) 가 브라우져에 도달하는 시간을 의미한다.
  • 브라우저가 DOM에서 첫 번째 콘텐츠 비트를 렌더링하여, 페이지가 실제로 로드되고 있다는 첫 번째 피드백을 사용자에게 제공하는 경우를 의미한다.

    Suspense를 사용하면 얻을 수 있는 이점

    1. 스트리밍 서버 랜더링 - 서버에서 클라이언트로 HTML을 점진적으로 랜더링한다.
    2. 선택적 Hydration - React는 사용자 상호작용을 기반으로 어떤 컴포넌트를 먼저 상호작용 가능하게 할지 우선순위를 정한다.

Redirecting

redirect : 사용자가 처음 요청한 URL이 아닌, 다른 URL로 보내는 것을 뜻한다.

Next.js에서 리디렉션을 처리할 수 있는 방법

API목적어디상태 코드
redirect돌연변이 또는 이벤트 후 사용자 리디렉션서버 구성 요소, 서버 작업, 경로 처리기307 (Temporary) or 303 (Server Action)
permanentRedirect돌연변이 또는 이벤트 후 사용자 리디렉션서버 구성 요소, 서버 작업, 경로 처리기308 (Permanent)
useRouter클라이언트 측 탐색 수행클라이언트 구성 요소의 이벤트 처리기해당 없음
redirects in next.config.js경로를 기반으로 들어오는 요청 리디렉션next.config.js파일307(임시) 또는 308(영구)
NextResponse.redirect조건에 따라 수신 요청 리디렉션라 수신 요청 리디렉션 미들웨어Any

redirect 기능

  • 사용자를 다른 URL로 리디렉션할 수 있다.
  • 서버 컴포넌트, 라우트 핸들러 및 서버 작업을 호출할 수 있다.
  • redirect돌연변이나 이벤트 후에 자주 사용됩니다.
'use server'
 
import { redirect } from 'next/navigation'
import { revalidatePath } from 'next/cache'
 
export async function createPost(id: string) {
  try {
    // Call database
  } catch (error) {
    // Handle errors
  }
 
  revalidatePath('/posts') // Update cached posts
  redirect(`/post/${id}`) // Navigate to the new post page
}

permanentRedirect 기능

  • 사용자를 다른 URL로 영구적으로 리디렉션할 수 있다.
  • 서버 컴포넌트, 라우트 핸들러 및 서버 작업을 호출할 수 있다.
  • 사용자 이름을 변경한 후 사용자의 프로필 URL을 업데이트하는 것과 같이 엔터티의 표준 URL을 변경하는 돌연변이 또는 이벤트 후에 자주 사용된다.
'use server'
 
import { permanentRedirect } from 'next/navigation'
import { revalidateTag } from 'next/cache'
 
export async function updateUsername(username: string, formData: FormData) {
  try {
    // Call database
  } catch (error) {
    // Handle errors
  }
 
  revalidateTag('username') // Update all references to the username
  permanentRedirect(`/profile/${username}`) // Navigate to the new user profile
}

useRouter()훅

useRouter는 Next.js에서 제공하는 Hook 중 하나로, 현재 페이지의 라우터 정보를 가져올 수 있게 해주는 기능이다. 이 Hook을 사용하면 현재 페이지의 URL, 쿼리 파라미터, 라우트 매개변수 등과 같은 라우터 정보에 접근할 수 있다.


Route Handlers

루트 핸들러는 웹의 요청/응답 API들을 이용하여 특정 루트에 커스텀 리퀘스트 핸들러를 생성할 수 있도록 도와준다.

알아두면 좋은 것: 루트 핸들러는 app디렉토리 내에서만 사용할 수 있습니다. 루트 핸들러들은 pages 디렉토리 내의 API Routes 와 동일하며, 이는 API Routes와 루트 핸들러를 함께 사용하지 않는다는 것을 의미합니다.

Convention (규약)

루트 핸들러는 app디렉토리 내의 route.js | ts파일에 정의한다:

export const dynamic = 'force-dynamic' // defaults to auto
export async function GET(request: Request) {}

루트 핸들러는 page.js나 layout.js와 비슷하게 app 디렉토리 내에 중첩될 수 있다. 하지만 page.js와 같은 루트 세그먼트 레벨에는 route.js파일이 올 수 없다.

Supported HTTP Methods (지원되는 HTTP 메서드)

다음과 같은 HTTP 메서드들이 사용 가능하다: GET, POST, PATCH, DELETE, HEAD, 그리고 OPTIONS. 지원되지 않는 메서드가 호출되면, Next.js는 405 Method Not Allowed 응답을 리턴합니다.

Extended NextRequest and NextResponse APIs (확장된 NextRequest와 NextResponse API)

네이티브 Request와 Response를 지원하는 것에 더불어, Next.js는 이 둘을 NextRequest, 그리고 NextResponse와 함께 확장하여 더 향상된 케이스들을 위해 편리한 도구들을 제공합니다

Behavior (행동 양식)

Static Route Handler (정적 루트 핸들러)

GET 메서드를 Response객체와 함께 이용할 경우, 루트 핸들러들은 기본적으로 정적으로 여겨진다.

// app/items/route.ts

import { NextResponse } from 'next/server';

export async function GET() {
	const res = await fetch('https://data.mangodb-api/com/...', {
    	headers: {
        	'Content-Type': 'application/json',
            'API-Key': process.env.DATA_API_KEY,
        }
    });
    const data = await res.json();
    
    return NextResponse.json({ data })
}

타입스크립트 경고: Response.json()은 유효하지만, 네이티브 타입스크립트의 타입들은 현재 에러를 보여준다. 타이핑된 응답에 대해서 NextResponse.json()을 대신 사용할 수 있다.

정적 페칭은 robots.txt, rss.xml, sitemap.xml 등의 루트들을 위한 커스텀 루트 핸들러를 생성하는 데에 유용할 수 있다.

Dynamic Route Handlers (동적 루트 핸들러)

루트 핸들러는 다음과 같은 경우에 동적이라고 여겨집니다:

  • Request 객체를 GET 메서드와 함께 사용하는 경우
  • 다른 HTTP 메서드들을 사용하는 경우
  • cookiesheaders와 같은 동적 함수들을 사용하는 경우

Route Resolution (루트 해결)

route를 가장 낮은 라우팅 원시 레벨로 고려할 수 있다.

  • page와 같은 클라이언트 사이드 네비게이션이나 레이아웃에 관여하지 않는다.
  • route.js 파일은 page.js 와 같은 루트에 위치할 수 없다.

next.js 공식문서

profile
Frontend Developer

0개의 댓글