[Next] 페이지별 레이아웃 설정하기

2024. 11. 18. 22:40·Next

🤔 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을 처리하는 방식이다.

  • NextPageWithLayout
    • NextPageWithLayout는 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
'Next' 카테고리의 다른 글
  • Firebase를 활용한 로그인 & 회원가입 구현하기 (feat. React Hook Form)
  • Next.js + Redux로 확장 가능한 모달 시스템 만들기 (with App Router)
  • [Next] API Routes
  • [Next] 프리페칭(Pre-fetching)
FE Dev. 굼지
FE Dev. 굼지
굼지의 웹 개발 레시피 입니다.
  • FE Dev. 굼지
    굼지의 웹 개발 레시피
    FE Dev. 굼지
    • 분류 전체보기 (14)
      • FrontEnd (3)
      • React (3)
      • Next (8)
      • React-Native (0)
  • 블로그 메뉴

    • 홈
    • 태그
  • 최근 글

FE Dev. 굼지
[Next] 페이지별 레이아웃 설정하기
상단으로

티스토리툴바