[NextJS] per-page Layout을 사용한 공통 레이아웃 적용
프로젝트를 진행하다보면 해당 애플리케이션의 레이아웃이 존재하게 되는데, 모든 페이지마다 레이아웃을 적용하기엔 반복적인 코드가 들어가기 마련이다.
그래서 오늘은 프로젝트 레이아웃을 공통적으로 적용하는 방법에 대해서 정리하면서, Nextjs 문서에서 소개하는 per-page Layout을 이용하여 다수의 레이아웃을 사용할 수 있는 방법에 대해서도 소개하도록 하겠다.
들어가기 전
일단 공통 레이아웃을 작성하기 전에 Nextjs의 구조를 한 번 살펴보자.
pages 폴더 내부에 존재하는 _app.tsx 파일은 서버에 요청이 들어가면 가장 먼저 실행되는 최상위 컴포넌트를 담당한다.
모든 페이지가 초기화 되기 전 해당 파일을 거쳐가기 때문에 애플리케이션의 전체적인 설정을 해줄 수 있는 공간이라고 표현해보겠다.
그렇다면 공통 레이아웃은 어떤 페이지에서 작성하면 될까? 위에서 살펴본 것처럼 _app.tsx 파일에서 작성해주면 된다.
공통 레이아웃 작성
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import {AppLayout} from "components/layout"
export default function App({ Component, pageProps }: AppProps) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
애플리케이션의 레이아웃에 맞게 Layout 컴포넌트를 하나 작성해서 _app.tsx 파일 내에서 사용한다.
Layout 컴포넌트로 감싸진 Component는 하나의 페이지를 뜻한다.
다수 레이아웃 사용( feat. per-page Layout)
애플리케이션의 레이아웃을 공통적으로 사용하지 않고 페이지마다 다른 레이아웃을 사용해야한다면 Nextjs에서는 per-page Layout을 사용하라고 권고한다.
페이지마다 다른 레이아웃을 지정해주는 getLayout 함수를 보면 Null 병합 연산자를 통해 Component.getLayout이 undefined 또는 null이 아닌 경우 해당 페이지에서 지정한 레이아웃을 사용하도록 한다.
// _app.tsx
import '@/styles/globals.css';
import { NextPage } from 'next';
import type { AppProps } from 'next/app';
import { ReactElement, ReactNode } from 'react';
import Layout from '@/components/common/Layout';
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode;
};
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
export default function App({ Component, pageProps }: AppPropsWithLayout) {
const getLayout = Component.getLayout ?? ((page) => <Layout>{page}</Layout>);
return getLayout(
<Component {...pageProps} />
);
}
특정 페이지 내에서 레이아웃을 지정해주는 경우에는 아래처럼 getLayout을 통해 레이아웃을 설정해줄 수 있다
// Auth/index.tsx
import { ReactElement } from 'react';
import { NextPageWithLayout } from '../_app';
import AuthLayout from '@/components/common/AuthLayout';
export const Auth: NextPageWithLayout = () => {
return <div>auth</div>
};
Auth.getLayout = function getLayout(page: ReactElement) {
return <AuthLayout>{page}</AuthLayout>
};
export default Auth;
만약 공통 레이아웃 내에 중첩 레이아웃이 필요한 경우에는 공통 레이아웃 내부에 특정 페이지 레이아웃을 지정해주면 된다.
이제 페이지 코드의 중복도 줄이고 작성하면서 일일이 레이아웃으로 감싸주지 않고도 공통 레이아웃을 작성할 수 있을것이다.
이번 포스팅도 많은 개발자 분들에게 도움이 되었으면 좋겠다.