본문 바로가기
개발/Next.js

Next.js에서 공통 레이아웃 설정하기

by 안뇽! 2023. 1. 13.
반응형

 

헤더나 푸터 같은 자주 재사용되는 컴포넌트들은 공통 레이아웃으로 한번에 선언하는 것이 좋다.

 

Layout이 1개일때

 

header와 footer는 알아서 만들고 우선 layout.tsx에 다음과 같이 설정하자.

 

// layout.tsx
import Header from "./Header";
import Footer from "./Footer";

export default function Layout({ children }: any) {
  return (
    <>
      <Header />
      <main>{children}</main>
      <Footer />
    </>
  );
}

 

그 후 _app.tsx에 Layout을 넣어주면 된다.

//pages/_app.tsx

import Layout from "../comonents/layout";
import "../styles/globals.css";
import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

 

Layout을 선택적으로 적용하고 싶을때

 

getLayout을 Layout을 적용하고 싶은 페이지에 추가해준다.

index.tsx와 other-home.tsx를 비교해보자.

// pages/index.tsx

const HomePage: NextPageWithLayout = () => {
  return (
    <>
      <Head>
        <title>june's blog</title>
      </Head>
      <h1>Welcome to June's blog</h1>
      <section>
        <Contents />
      </section>
    </>
  );
};

//다음 getLayout을 추가
HomePage.getLayout = function getLayout(page: ReactElement) {
  return <Layout>{page}</Layout>;
};

export default HomePage;

 

// pages/other-home.tsx

const otherHome = () => {
  return (
    <div>
      <Header />
      otherHome
    </div>
  );
};

export default otherHome;

index.tsx에는 getLayout함수를 설정하였지만, other-home.tsx는 getLayout함수를 설정하지 않았다.

 

그리고 _app.tsx에는 props로 받은 Component에 getLayout이 없다면 page를 그대로 반환하도록 getLayout을 선언했다.

//_app.tsx
import { ReactElement, ReactNode } from "react";
import Layout from "../comonents/layout";
import "../styles/globals.css";
import type { AppProps } from "next/app";
import { NextPage } from "next";
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: any) => page);
  return getLayout(<Component {...pageProps} />);
}

 

이렇게 되면

 

page/index.tsx의 경우 <Layout><page /></Layout>을 반환하여서 Header와 Footer가 있는 페이지가 렌더링되지만,

page/other-home.tsx의 경우 <page />만 반환하면서 Footer가 없는 페이지가 렌더링된다.


참고

https://nextjs.org/docs/basic-features/layouts

반응형