[NextJS] 자주쓰는 패턴, Layout

최예린·2023년 7월 30일
0

NextJS

목록 보기
7/8

NextJS 최신버전에서는 프로젝트를 생성하면 app 폴더에 layout.js가 자동으로 생성된다. 그리고 그 안에는


export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

이렇게 메타데이터를 설정하는 코드가 기본으로 들어있다.
강의에서는 components폴더에 Seo.js를 따로 만들어서 next/head에서 제공하는 Head 컴포넌트를 각 페이지마다 import하고 있다.
그냥 head를 쓰는 것과 어떤 차이점이 있는지 궁금해서 chatGPT한테 물어보았다.

  • next/head의 <Head> 컴포넌트와 <head> 차이점 ChatGPT 답변
    "next/head"는 Next.js 프레임워크에서 제공하는 기능으로, 서버 측 렌더링과 클라이언트 측 렌더링 간의 차이를 줄이고 웹 애플리케이션의 성능과 검색 엔진 최적화를 개선하는데 도움을 줍니다. 일반 "head" 태그와의 주요 차이점은 다음과 같습니다:
  • 서버 측 렌더링 (Server-side rendering):
    "next/head" 컴포넌트를 사용하면 해당 페이지의 헤드 부분이 서버 측에서 렌더링됩니다. 이는 웹 페이지가 처음 로드될 때 필요한 메타데이터, 스타일 시트, 스크립트 등의 정보가 서버에서 클라이언트로 전송되어 초기 로딩 속도를 개선하는데 도움을 줍니다.

  • 코드 스플리팅 (Code splitting):
    Next.js는 페이지별로 자동으로 코드 스플리팅을 수행하여 필요한 자바스크립트 파일을 최적화하고 로딩 속도를 향상시킵니다. "next/head"를 사용하면 해당 페이지와 관련된 자바스크립트 파일의 코드 스플리팅도 자동으로 이루어집니다.

  • 서버에서의 최적화:
    Next.js는 "next/head" 컴포넌트를 사용하여 서버에서 페이지의 헤드 부분을 미리 파싱하고 최적화합니다. 이로 인해 검색 엔진 최적화(SEO)에 유리한 페이지가 생성될 수 있습니다. 일반 "head" 태그를 사용할 때는 클라이언트에서 자바스크립트가 로드된 후에 헤드 부분이 생성되므로 SEO에 미치는 영향이 다소 달라질 수 있습니다.

  • 컴포넌트 기반 사용:
    "next/head"는 Next.js의 컴포넌트로 제공되기 때문에, 다른 컴포넌트와 함께 사용하기 용이합니다. 이를 통해 코드의 재사용성과 유지보수성이 향상됩니다.

요약하면, "next/head"를 사용하면 Next.js의 기능과 최적화를 활용하여 웹 애플리케이션의 성능과 SEO를 향상시킬 수 있습니다. 일반 "head" 태그를 사용하는 경우에는 이러한 기능과 최적화가 제한될 수 있습니다. 따라서 Next.js 프로젝트에서는 페이지의 헤드 부분에 "next/head" 컴포넌트를 사용하는 것이 좋습니다.


이런 차이점이 있다. 강의 댓글에서는 pathname과 title에 들어갈 문자열을 딕셔너리로 생성해서 pathname에 따라 title이 자동으로 바뀌도록 추가적인 개선방안도 제안하고있었다.

일단 Head 컴포넌트를 사용해보겠다.

Error: Hydration failed

Error: Hydration failed because the initial UI does not match
what was rendered on the server.

Warning: Expected server HTML to contain a matching <html>in <div>.

See more info here: https://nextjs.org/docs/messages/react-hydration-error

서버사이드에서 pre-rendering된 React 트리와 브라우저에서 처음 rendering되는 React 트리가 달랐기 때문에 발생하는 에러라고한다.

Error: There was an error while hydrating.
Because the error happened outside of a Suspense boundary,
the entire root will switch to client rendering.

chatGPT한테 물어봤을때는 Suspense에 관한 문제라는 답변이 돌아오기도했다. 하지만 나는 Suspense를 쓰지도않았다.

뭐가 문제일까싶어서 강의 코드와 가장 큰 차이점인 layout.js 코드를 지우고(프로젝트 생성시 기본 제공되는 코드지만) 강의의 layout.js 코드를 사용하니 모든 에러가 해결됐다.

  • 최신 NextJS에서 기본 생성되는 layout.js 코드
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  )
}

이렇게 html로 감싸져있다.

client.js:1 Warning: validateDOMNesting(...): <html> cannot appear as a child of <div>.

layout 컴포넌트를 _app.js에서 import해서 사용하고있는데 이게 화근이었을까.

  • _app.js
export default function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}
react-dom.development.js:19849 Uncaught Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.

공식 문서를 보니 강의에서 나온 코드를 사용하고있다. 그래서 미련없이 지우고 강의 코드를 따라가기로했다.

그리고 이제 처음 배우는 단계라서 그런지 _app.js에서 전역적인 처리를 해주고 있는데 왜 굳이 Layout으로 한번 더 감싸는지 이해가 잘 되지않는다. 강의에서는 App Component가 길어지는걸 원치않는다고 하긴했다.

profile
경북대학교 글로벌소프트웨어융합전공/미디어아트연계전공

0개의 댓글