Routing and Page Rendering

라우팅 및 페이지 렌더링 - 심층분석

  • app/icon.jpg \(\rightarrow\) 즉시 favicon으로 사용
  • 모든 page component 에 암묵적으로 들어가는 Param 있음 -> 동적 라우팅 가능

∥ Parallel Routes

병렬 라우트

  • @ 처리
archive/
├── @latest/
│   └── page.ts
├── @archive/
│   ├── page.ts
│   └── [slug]/
│       └── page.ts
└── layout.ts
  • 자동으로 layout param으로 들어감 !

    const ArchiveLayout({archive, layout}) => {
      return (
        <>
          {archive}
          {latest}
        </>
      )
    }
    
    • 문제: /archive/1211 불가 (latest > [slug]가 없음)
    • 해결: latest/default.ts
      • 병렬 라우팅 되더라도 얘 보여줌 (no matter which slug)

🎣 Catch-All Routing

  • layout에 navbar 넣는 대신 이거 해도 좋음
archive/
├── @archive/
│   ├── [[...filter]] <<<<<<<<<----- Catch-all
│   │    └── page.ts
└── layout.ts
  • catches ALL params after archive/
    • archive/, archive/2024, archive/2024/12112

Error.tsx

  • 잘못된 url 입력해서 params에서 감지 불가 시, throw Error을 한다고 하자
  • Error.ts 파일을 생성해두면 해당 컴포넌트가 렌더링 됨 (에러 대신)

⚠️ 반드시 “use client”로 만들 것 error may work on both ends, (client components works on both ends) => error fallback must be availabe on both sides


Revisiting Server vs Client Components

React Server Components (RSC)Client Components
ONLY rendered on serverpre-rendered in server,
client에서도 가능
default in NEXTJS 
  • error.ts, usePathName() 같은 훅 사용하려면 “use client”로 해서 client component로 변경해야 함
  • 최대한 further down the tree로…

Nested Dynamic Routing, Intercepting

  • posts/[id]/images 요런거 가능

  • Intercepting Routes

    posts/
    ├── [id]/
    │   ├── (.)images/ <<<<<<<----- intercept 로 진입 경우
    |   |   └── page.tsx
    │   └── images/
    │       └── page.tsx
    └── layout.ts
    
    • parellel 라우팅 사용 시 특히 유용함 (모달 vs full screen)
    posts/
    ├── [id]/
    │   ├── @modal
    |   |   └── (.)images
    |   |        └── page.tsx (must return at least null)
    |   |   └── page.tsx
    │   └── images/
    │       └── page.tsx
    └── layout.ts (modal 추가)
    
  • 오류 발생할 수도 있음

    • 해결: page.tsx -> default.tsx로 변경해보기

next/useRouter

  • useRouter로 라우터 정보 가져오기

    • use client로 만들어야 함
    const router = useRouter();
    const goBack = () => router.back();
    

Route Groups

app/
├── posts/ ...
├── page.tsx
└── layout.tsx
  • (ROUTE GROUP)은 url에 적용되지 않음
  • 예) 최상위 layout.tsx에 네비게이션바가 있으나 랜딩페이지 (page.tsx) 에는 빼고 싶을 때:
app/
├── (content)/  ( ROUTE GROUP )
│   ├── posts/ ...
│   └── layout.tsx  <<<<<<<----- 네비게이션 포함
└── (landing)/ ...  ( ROUTE GROUP )
    └── page.tsx    <<<<<<<----- 여기 land함
    └── layout.tsx  <<<<<<<----- 네비게이션 빠진 레이아웃

Route Handlers

  • ex: api/route.ts
  • 따로 Page.tsx나 layout.tsx 불필요 (페이지를 렌더링 하지 않음)
  • exports GET, POST, PUT, DELETE, PATCH 하는 함수들
export async function GET(request) {
  console.log("GET request", request);

  return new Response("Hello World");
}
  • localhost:3000/api 로 접근 시 Hello World 출력
  • 터미널에서는 GET request 출력

MiddleWares, matchers

  • does NOT use app/
  • middleware.ts 파일 생성
import { NextResponse } from "next/server";

export const middleware = (request) => {
  // forwards to next middleware
  return NextResponse.next();
};
  • then it would run for ALL requests sent to the server (including image fetches, etc.)
export const config = {
  matcher: "/posts",
};
  • only runs for requests that match the given path