코드노트

Next.js 13 SSR에서 현재경로 가져오기 실패 기록 본문

Code note/Error문제해결

Next.js 13 SSR에서 현재경로 가져오기 실패 기록

코드노트 2023. 7. 10. 02:11

현재 진행하고 있는 사이트에서 푸터 컴포넌트를 넣었다.

모든 페이지에서 보여주지 않고 특정 페이지에서는 보여주지 않게 하고 싶었다.

 

Next.js 13버전을 사용하고 있었고, 서버컴포넌트를 사용하려고 했지만 현재경로를 가져오려면 클라이언트 컴포넌트를 사용해야했다.

푸터는 변화가 없기 때문에 특정 페이지의 path만 얻어올 수 있으면 SSR을 사용하는게 맞다고 판단하였다.

 

그럼 어떻게 SSR에서 use 훅을 사용하지 않고 들고올 수 있을까?

 

 

[Next 13] Server Component + Layout.tsx - Can't access the URL / Pathname · Issue #43704 · vercel/next.js

Verify canary release I verified that the issue exists in the latest Next.js canary release Provide environment information Operating System: Platform: linux Arch: x64 Binaries: Node: 19.0.1 npm: 8...

github.com

next.js github에서 issue에 해결되지 않은 문제를 발견했다.

다른 사람들도 서버컴포넌트에서 현재경로를 가져올 수 있는 방법들을 찾고 있었다.

역시 나만 불편한게 아니였어..

 

작년 12월에 올라온글은 이 글을 작성하는 2일 전까지도 문제에 있어서 이야기가 오고가고 있었다.

 

그중에서 가장 효과적인것 같은 방법으로 시도해보았다.

방법은 미들웨어를 사용하는거였다.

Next.js에서는 middleware를 사용할 수 있는데 전체 APP에서 접근가능하기 때문에 효과적이라고 생각했다.

다른 사람들도 좋아요를 눌러놨기 때문에 오 해결가능하겠는데...? 라는 생각을 하며 코드를 작성했다...

 

// /middleware.ts
import { NextResponse } from 'next/server';

export function middleware(request: Request) {
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('x-url', request.url);
  return NextResponse.next({
    request: {
      headers: requestHeaders,
    }
  });
}

미들웨어를 우선 src 최상위 경로에 작성해준다.

- 요청이 처리되기전 현재 요청의 헤더를 복사하여 수정가능한 객체에 새로운 헤더를 생성한다.

- x-url이라는 이름으로 현재 요청의 URL을 설정한다.

- NexrResponse.next()를 호출하여 미들웨어로 제어를 전달하고 변경된 헤더를 적용한 새로운 요청 객체를 반환시킨다.

 

그럼 이제 페이지를 이동할때마다 현재 요청 URL을 감지할 수 있고 서버컴포넌트에서도 페이지 경로마다 가능할 줄 알았다.

 

 

import { headers } from 'next/headers';

const FOOTER_UNLIST = ["login", "join"];

const headersList = headers();
const header_url = headersList.get("x-url") || "";
const isValueIncluded = FOOTER_UNLIST.some(value => header_url.includes(value));

- 이제 사용할 Footer 컴포넌트 내에서 headers()를 가지고와서 호출한 후 url을 가지고와 비교했다.

- 우선 login, join 에서는 푸터를 사용할 필요가 없기때문에 some을 통해 false일때만 forter를 보여주도록 로직을 작성했다. 

 

 

오!!! 서버에서 확인이 가능했다.

푸터도 login, join에서는 보이지 않았다.

해결되었나!? 라고 생각하고

다시 login페이지를 들어가보니 이미 ssr로 그려진 페이지는 서버에서 새로 url을 확인할 수 없었다..

 

문제점

- 처음 페이지를 들어갈때는 서버에서 페이지를 들고오면서 페이지 경로 URL을 확인하여 컴포넌트를 조건부렌더링할 수 있다.

- 그 뒤에 같은 페이지를 방문할때는 이 페이지의 경로를 읽을 수 없기 때문에 조건부 렌더링이 실행되지 않는다.

 

 

🤔 여기서 들었던 생각.

- 서버 컴포넌트라도 이렇게 현재 경로를 감지하여야하는 경우라면 서버컴포넌트에 제한적이다.

- 렌더링 방식에 있어서 사용자의 로그인 유무, 데이터의 가변적인가를 생각했지만 이러한 문제에 있어서도 생각해야 하는것을 알게 된것 같다.

 

그래서 결국 footer는 클라이언트 컴포넌트로 마무리를 지었다..