Next.js
Server Component와 Client Component 구분하기
내 블로그는 Next.js로 돌아간다.
포스트의 내용 중 링크가 있으면 Open Graph로 보여주는데, 이를 통해 해당 링크의 제목, 이미지 등 대표적인 내용을 보여줄 수 있다.
링크에서 Open Graph의 내용을 가져오려면 네트워크 요청을 보내야 한다.
그렇기 때문에 server component에서는 async 컴포넌트로 데이터를 가져온 후 렌더링해서 보내준다.
if (href != null && href === children?.toString()) {
return <OpenGraphBlock url={href} />
}
:: 기존의 서버 사이드 Open Graph 렌더링 컴포넌트 ::
문제는 포스트를 쓰는 중 "미리보기"를 할 때 발생했다.
미리보기는 포스트의 내용을 서버에서 렌더링하는 것이 아니라 클라이언트에서 가지고 있는, 현재 작성 중인 내용을 가지고 렌더링한다.
같은 Open Graph 컴포넌트를 사용하면 클라이언트 사이드에서 async 컴포넌트를 호출하게 되는 것이다.
이는 다음과 같은 에러를 발생시켰다.
Application error: a client-side exception has occurred (see the browser console for more information).
클라이언트 사이드에서 async 컴포넌트를 렌더링할 수 없어서 생긴 에러였다.
이 에러가 발생하는 것은 진작 알고 있었지만 어차피 게시글은 나 혼자 쓰는 것, 그냥 조금 조심하면서 쓰면 되지 하는 마인드로 미뤄놨었다.
그러나 링크를 많이 사용할 포스트를 작성할 일이 생겨, 수정하기로 했다.
이를 해결하기 위해서는 현재 컴포넌트가 서버 사이드에서 렌더링 되는지, 클라이언트 사이드에서 렌더링 되는지를 알아야 했다.
typedef window == 'undefined'
방법은 매우 간단했다.
window가 정의되어 있는지를 확인하면 됐다.
서버 사이드의 경우 window 객체가 없기 때문에 그 타입이 undefined이다.
이를 활용하면 undefined인 경우 서버 사이드, 그렇지 않은 경우 클라이언트 사이드임을 알 수 있다.
if (typeof window == 'undefined') {
return <OpenGraphBlockServer url={href} />
} else {
return <OpenGraphBlockClient url={href} />
}
:: 렌더링 위치를 구분한 Open Graph 컴포넌트 ::
이제 게시글을 작성할 때에도 링크 포함 여부 상관 없이 미리 보기를 보면서 작성할 수 있게 되었다.
02024. 12. 25.