🤔 Next.js 는 기본적으로 전역적인 레이아웃을 제공하지만, 특정 페이지마다 다른 레이아웃을 적용하려면 어떻게 해야 할까?
☑️ 레이아웃 적용 방법의 개념
Next.js에서는 기본적으로 페이지를 pages 폴더 아래에 작성하고, 각 페이지는 독립적으로 렌더링된다. 이때 각 페이지마다 다른 레이아웃을 적용하고 싶을 수 있다. 이를 위해 Next.js에서는 getLayout이라는 특수한 메서드를 활용하여 각 페이지에 맞는 레이아웃을 설정할 수 있다.
우선 전체적인 코드를 살펴보자
pages/_app.tsx
import GlobalLayout from "@/components/global-layout";
import "@/styles/globals.css";
import { NextPage } from "next";
import type { AppProps } from "next/app";
import { ReactNode } from "react";
// 페이지에 레이아웃을 지정할 수 있는 타입 정의
type NextPageWithLayout = NextPage & {
getLayout?: (page: ReactNode) => ReactNode;
};
export default function App({
Component,
pageProps,
}: AppProps & { Component: NextPageWithLayout }) {
// 페이지에서 지정한 레이아웃을 불러옴, 없다면 기본적으로 페이지 자체를 반환
const getLayout = Component.getLayout ?? ((page: ReactNode) => page);
return <GlobalLayout>{getLayout(<Component {...pageProps} />)}</GlobalLayout>;
}
_app.tsx는 Next.js에서 모든 페이지에 공통적으로 적용되는 파일이다. 여기서 중요한 부분은 getLayout을 처리하는 방식이다.
NextPageWithLayoutNextPageWithLayout는NextPage타입을 확장한 타입으로, 각 페이지에서getLayou메서드를 사용할 수 있도록 한다.- 이 메서드는
page를 인자로 받아, 해당 페이지를 감싸는 레이아웃을 반환하는 역할을 한다.
getLayout처리- 여기서
GlobalLayout컴포넌트는 기본 레이아웃을 제공하는 컴포넌트로, 모든 페이지에 공통적으로 적용된다. 그 안에getLayout에서 반환한 레이아웃을 감싸서 렌더링한다.
- 여기서
pages/index.tsx
import SearchableLayout from "@/components/searchable-layout";
import { ReactNode } from "react";
// 기본 페이지 내용
export default function Home() {
return <h1>인덱스</h1>;
}
// `getLayout`을 통해 `SearchableLayout`을 설정
Home.getLayout = (page: ReactNode) => {
return <SearchableLayout>{page}</SearchableLayout>;
};
여기서 중요한 점은 Home.getLayout을 사용하여 페이지에 SearchableLayout을 적용한 것이다.Home.getLayout = (page: ReactNode) => { ... }를 통해 Home 페이지에 SearchableLayout을 적용한다. 이렇게 하면, Home 페이지가 렌더링될 때, 기본 레이아웃이 아닌 SearchableLayout이 감싸게 된다.
☑️ 레이아웃 관리의 장점
- 페이지별 맞춤형 레이아웃: 각 페이지에서
getLayout을 정의함으로써, 페이지별로 다른 레이아웃을 쉽게 적용할 수 있다. - 기본 레이아웃 유지:
GlobalLayout을 사용하여, 모든 페이지에서 기본적인 레이아웃을 유지하면서도, 페이지별로 특화된 레이아웃을 추가할 수 있다. - 유연성: 페이지별 레이아웃을 자유롭게 정의할 수 있어, 복잡한 UI 요구사항을 가진 애플리케이션에서 유용하다.
🤔 그렇다면 GlobalLayout과 SearchableLayout은 각각 어떻게 구성될까?
☑️ GlobalLayout와 SearchableLayout 예시
GlobalLayout.tsx
import { ReactNode } from "react";
const GlobalLayout = ({ children }: { children: ReactNode }) => {
return (
<div>
<header>헤더</header>
<main>{children}</main>
<footer>푸터</footer>
</div>
);
};
export default GlobalLayout;
GlobalLayout은 모든 페이지에 공통적인 헤더와 푸터를 제공하는 기본 레이아웃이다. 이 레이아웃은 각 페이지에서 getLayout을 통해 다른 레이아웃을 적용할 때에도 기본적으로 유지된다.
SearchableLayout.tsx
import { ReactNode } from "react";
const SearchableLayout = ({ children }: { children: ReactNode }) => {
return (
<div>
<header>
<input type="search" placeholder="검색" />
</header>
<main>{children}</main>
</div>
);
};
export default SearchableLayout;
SearchableLayout은 검색 기능을 제공하는 레이아웃이다. 이 레이아웃은 특정 페이지에만 적용되며, 검색 입력창이 포함된 구조를 가지고 있다.
pages/index.tsx 에서 Home.getLayout을 사용하여 페이지에 SearchableLayout을 적용했으니, pages/test 경로에서는 SearchableLayout 에 적용한 검색 입력창이 노출되지 않을 것이다.
🎓 정리
👍 Next.js에서 페이지별로 다양한 레이아웃을 적용하려면, getLayout을 활용하는 방식이 매우 유용하다. 이를 통해 애플리케이션에서 각 페이지에 맞는 레이아웃을 자유롭게 설정할 수 있으며, 기본 레이아웃과 특정 레이아웃을 병행하여 사용할 수 있다. 이러한 방식은 특히 큰 애플리케이션에서 레이아웃을 일관되게 관리하고, 페이지마다 유연한 레이아웃을 적용하는 데 도움이 된다.
'Next' 카테고리의 다른 글
| Firebase를 활용한 로그인 & 회원가입 구현하기 (feat. React Hook Form) (0) | 2025.05.13 |
|---|---|
| Next.js + Redux로 확장 가능한 모달 시스템 만들기 (with App Router) (0) | 2025.05.06 |
| [Next] API Routes (3) | 2024.11.15 |
| [Next] 프리페칭(Pre-fetching) (0) | 2024.11.07 |
| [Next] 페이지 라우터(Page Router) (2) | 2024.11.06 |