Next.js 13 multiple layout 적용하기

버건디·2023년 7월 17일
2

Next.js

목록 보기
42/52
post-thumbnail

❗️ 해당 글은 이 글에 작성 된 해결 방법으로 대체되었습니다 ❗️

프로젝트를 만드는 와중에, register 페이지만 아예 다른 레이아웃을 보여주고 그 외의 모든 페이지엔 공통된 레이아웃을 적용시키고 싶었다.

기본적으로 Next.js 13 app router 에서는 nested layout 구조이기때문에, 각 페이지마다 layout.tsx를 만들어주어도

메인 레이아웃이 그 다른 레이아웃을을 감싸는 구조가 된다.

하지만 저 Register 페이지에서는 아예 다른 레이아웃을 보여주고 싶었다.

- 대략적인 root layout.tsx 구조

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {

  return (
    <html>
      {/*
        <head /> will contain the components returned by the nearest parent
        head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
      */}
      <head />
      <body suppressHydrationWarning={true}>
        <script
          dangerouslySetInnerHTML={{
            __html: themeInitializerScript,
          }}
        ></script>
        <Providers>
          <Card>
            <Header />
            <ContentCard>{children}</ContentCard>
            <Foorter />
            <div id="portal"></div>
          </Card>
        </Providers>
      </body>
    </html>
  );
}

- 다른 레이아웃 적용할 register 페이지 layout.tsx

import "../globals.css";
import Header from "@/components/Header/Header";
import ContentCard from "@/components/Card/ContentCard";
import Providers from "@/redux/Providers";

export default function RegisterLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <Providers>
        <ContentCard>{children}</ContentCard>
      </Providers>
    </>
  );
}

메인 페이지에만 body와 html태그가 존재하면 되고, 다른 레이아웃들에서는 구조를 새롭게 잡아주면되는데, 문제는 이 다른 레이아웃을 적용할 페이지에서 root 레이아웃에 존재하는 헤더 컴포넌트가 계속 등장했다.

(위에 보이는 선이 헤더컴포넌트)


공식문서를 보며 다시 생각해야할점은 root layer는 무조건 결국 전부 모든 페이지에 적용 된다는 것이다.

그렇기때문에 root layer 는 최소한의 컴포넌트를 두고, 그 후에 선택적으로 추가/제거할 컴포넌트를 적용시켜 주면된다.

Header 와 Footer 컴포넌트는 무조건 메인페이지에 등장해야 하므로 page.tsx 자체내에서 임포트 해주었다.

- root layout.tsx

    <html lang="en" className={nanumGothicFont.className}>
      {/*
        <head /> will contain the components returned by the nearest parent
        head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
      */}
      <head />
      <body suppressHydrationWarning={true}>
        <script
          dangerouslySetInnerHTML={{
            __html: themeInitializerScript,
          }}
        ></script>
		// redux 프로바이더로 전역 감싸주기
        <Providers>
          {children}
          <div id="portal"></div>
        </Providers>
      </body>
    </html>

- root page.tsx

import MainLinks from "@/components/Body/MainLinks/MainLinks";
import Header from "@/components/Header/Header";
import Foorter from "@/components/Footer/Footer";
import Card from "@/components/Card/Card";
import ContentCard from "@/components/Card/ContentCard";

export default function Home() {
  return (
    <>
      <Card>
        <Header />
        <ContentCard>
          <MainLinks />
        </ContentCard>
        <Foorter />
      </Card>
    </>
  );
}

- 다른 페이지 layout.tsx

import "../globals.css";
import Header from "@/components/Header/Header";
import Card from "@/components/Card/Card";
import ContentCard from "@/components/Card/ContentCard";
import Footer from "@/components/Footer/Footer";

export default function PlayingPageLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <Card>
        <Header />
        <ContentCard>{children}</ContentCard>
        <Footer />
      </Card>
    </>
  );
}
  1. multiple layout을 적용해야한다면 root 레이아웃에는 최소한의 컴포넌트만 적용시키고 메인 페이지에서 필요한 컴포넌트들을 임포트한다.

  2. multiple layout을 만들어준다.

profile
https://brgndy.me/ 로 옮기는 중입니다 :)

2개의 댓글

comment-user-thumbnail
2023년 7월 17일

잘봤습니다. 좋은 글 감사합니다.

답글 달기
comment-user-thumbnail
2023년 7월 17일

저도 개발자인데 같이 교류 많이 해봐요 ㅎㅎ! 서로 화이팅합시다!

답글 달기