본문 바로가기
배움 기록/Next.js

[Next.js] _app.js와 _document.js에 대해서

by dygreen 2022. 12. 26.
Next.js의 _app과 _document에 대해서 알아보겠습니다


 

 

📌 _app

  • 가장 먼저 실행되는 컴포넌트 → 모든 페이지는 _app을 통해 실행됨 → 모든 페이지에서 필요한 처리를 할 수 있음
  • 각각의 페이지가 초기화될 때 로딩되는 파일 → 자신이 원하는 로직으로 페이지를 초기화할 수 있음

 

위와 같은 특징들로 인해 _app의 대표적인 사용 예는 다음과 같다.

 

  1. 각 페이지의 공통된 레이아웃 페이지 작성
  2. 전체 앱에 Global CSS 적용
  3. Redux Provider 설정
import "../styles/globals.css";
import type { AppProps } from "next/app";
import Layout from "../components/layout";

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

 

👆 위의 코드는 기본적인 _app.tsx 에 공통된 레이아웃(<Layout>)을 추가했을 경우의 한 예시이다.

 

각각의 코드를 하나하나 살펴보면 다음과 같다.

  • <Layout> : 공통된 레이아웃 페이지 컴포넌트
  • <Component> : 현재 페이지를 의미 → 페이지가 변경되면 Component가 변경됨
  • pageProps : getInitialProps, getStaticProps, getServerSideProps 중 하나를 통해 가져온 초기 속성값을 의미 → 해당 값들이 없다면 빈 객체를 반환함 (* _app은 getStaticPropsgetServerSideprops를 지원하지 않음) 

 


 

_app에서도 getInitialProps를 사용해 모든 페이지에서 사용할 공통 속성값을 지정할 수 있으나, 이 경우 자동 정적 최적화(Automatic Static Optimization)이 비활성화되어 모든 페이지가 SSR를 통해 제공된다.

 

getInitialProps를 사용하고자 한다면, 아래 코드처럼 App 객체를 불러온 후 getInitialProps를 통해 데이터를 불러와야 한다.

import App from "next/app"

function app({ Component, pageProps }) {
    return <Component {...pageProps} />
  }
   
app.getInitialProps = async (appContext) => {
  const appProps = await App.getInitialProps(appContext);
  
  return { ...appProps }
}

 


 

[참고하실 분만 보시면 됩니다🙂]

React-Bootstrap + Redux 셋팅 ver.

이번에 진행하는 프로젝트에서 React-Bootstrap과 Redux toolkit을 사용하였는데,

해당 기능을 사용하기 위해 셋팅한 코드는 다음과 같다.

import 'styles/globals.scss'
import type { AppProps } from 'next/app'
import { SSRProvider } from 'react-bootstrap'
import 'bootstrap/dist/css/bootstrap.min.css'
import { store } from "modules/flags"
import { Provider } from "react-redux"

config.autoAddCss = false

const MyApp = ({ Component, pageProps }: AppProps) => {

  return (
    <SSRProvider>
      <Provider store={store}>
          <Layout>
              <Component {...pageProps} />
          </Layout>
      </Provider>
    </SSRProvider>
  )
}

export default MyApp

 

📌 _document

  • _app 다음에 실행
  • 서버에서만 실행됨 → [주의] 브라우저 api 또는 이벤트 핸들러는 실행되지 않기 때문에 해당 로직은 추가하지 않음 (+CSS도 사용x)

 

위와 같은 특징들로 인해 _document의 대표적인 사용 예는 다음과 같다.

>> 모든 페이지에서 공통으로 사용하는 <html>, <head>, <body>를 커스텀할 때 사용함

 

[주의] 

  •  모든 페이지에서 공통적으로 적용되어야 하는 <head>만 넣고, <title> 같이 페이지마다 바뀌는 것들은 각 페이지 별로 넣어야 함
  •  _document에서는 "next/document"의 Head를 사용함 → 그 외 컴포넌트에서는 "next/head"의 Head를 사용함
  •  _document 또한 getStaticProps와 getServerSideProps를 지원하지 않음
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

 


 

참고 :
https://talkwithcode.tistory.com/96
https://merrily-code.tistory.com/154
https://nextjs.org/docs/advanced-features/custom-app
https://nextjs.org/docs/advanced-features/custom-document
728x90

댓글