Next 버전 13.4이후로 App router 방식이 도입되면서, 기본적으로 모든 컴포넌트는 서버 컴포넌트(SRC)로 생성된다. 클라이언트 컴포넌트(CRC)로 사용하기 위해서는 컴포넌트 최상단에 use client를 명시해주면 된다.
그러나 Root Layout은 CRC로 사용할 수 없다❗️❗️
현재 url을 가져오는 usePathname() 는 무조건 CRC 내부에서만 사용 가능하다. 이를 해결하기 위해 SRC와 CRC를 혼합한 방법으로 Root Layout에서 pathname을 얻어올 수 있다.
pathname에 따라 layout 내부 TopBar의 아이콘을 보여줄지 말지 결정하고 배경색 또한 다르게 설정한다.// app/top-var.tsx
'use client'
import { usePathname } from 'next/navigation';
import Logo from '../../public/svgs/logo.svg';
import Profile from '../../public/svgs/profile.svg';
export function TopBar() {
const pathname = usePathname();
console.log(pathname);
return (
<div className={`h-24 px-8 flex flex-row justify-between items-center ${pathname.includes('/meeting') ? 'bg-black' : 'bg-white'
} `}>
<div className="flex">
<Logo width={30} height={30} />
<h1 className="mx-2 text-3xl font-semibold text-primary">C.A.M</h1>
</div>
<button>
// meeting 페이지에서는 Profile 아이콘 제외
{pathname.includes('/meeting') ? '' : <Profile />}
</button>
</div>
)
}
// app/layout.tsx
import type { Metadata } from 'next';
import localFont from 'next/font/local';
import './globals.css';
import { TopBar } from './top-bar';
const pretendard = localFont({
src: '../../public/fonts/PretendardVariable.woff2',
display: 'swap',
weight: '45 920',
variable: '--font-pretendard',
});
export const metadata: Metadata = {
title: 'CAM',
description: 'This is online meeting platform, CAM',
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="kr" className={`${pretendard.variable}`}>
<body className={`${pretendard.variable} h-screen flex flex-col`}>
// TopBar 컴포넌트 import
<TopBar />
<div className="flex h-full w-full">{children}</div>
</body>
</html>
);
}