Frontend/NextJS

[Next.js] _app, _document, _error

findmypiece 2021. 9. 24. 01:42
728x90

Next.js 의 pages 디렉토리는 파일기반으로 라우팅 기능이 수행되게 하는 핵심적인 역할을 한다. 이 안에서도 특별한 역할을 하는 파일들이 있는데 _app.jsx, _document.jsx, _error.jsx 파일들이다.(타입스크립트를 사용한다면 확장자는 .tsx 가 될 것이다) 이 파일들이 필수로 필요한 것은 아니지만 그 특징을 활용하면 보다 효율적으로 개발할 수 있다.

 

_app.jsx 파일의 경우 페이지의 body 부분이 만들어지기 전에 호출되기 때문에 pages 하위의 특정 페이지가 호출될 때 공통으로 적용할 header, footer 등을 추가할 수 있게 된다. 이에 레이아웃 정의시 활용될 수 있다.


_document.jsx 파일의 경우 _app.jsx 에 의해 만들어진 body를 토대로 실제 html 페이지를 만들어서 랜더링할 때 호출된다. 이에 html 의 head 부분에 해당하는 meta, link 등을 정의할 수 있다. 모든 페이지에 공통으로 적용될 title 이나 cdn에서 다운받아서 적용할 global css, js 등을 정의할 수 있다. 

 

_document.jsx 는 Class 형 컴포넌트만 지원하며 다음 4가지 컴포넌트는 필수로 존재해야 한다.

  • <Html>
  • <Head>
  • <Main>
  • <NextScript>

참고로 <Head> 는 next/head의 Head와 next/document의 Head가 있는데 _document.js에서 사용하는 게 next/document 의 Head 이고 실제 컴포넌트에서 사용하는게 next/head의 Head 이다.

 

 

next/document의 Head는 next/head의 Head 를 감싸는 역할만 하고 실제 head와 동일한 동작을 하는 것은 next/head 의 Head 이다. 

 

 

그렇다면 공통 헤더는 어떻게 정의해야 할까? 방법은 2가지를 생각해볼 수 있다.

1. _document.jsx 내부 next/document의 Head에 정의하는 방법

2. 별도의 Header 컴포넌트를 만들어서 next/head의 Head를 정의하고 이를 _app.jsx 레이아웃에 포함하는 방법

 

참고로 next/head의 Head는 각 페이지 컴포넌트에도 포함할 수 있는데 위의 1번 방법과 함께 사용할 경우 단순히 병합되고 2번 방법과 함께 사용할 경우 2번의 Head 내용이 상속되고 페이지 컴포넌트에서 재정의할 경우 오버라이드 된다.

 

예를 들어 head 의 title 태그를 공통헤더와 페이지 헤더에 둘 다 적용했다고 가정해보자. 공통헤더를 1번 방법으로 적용했을 경우 해당 페이지를 실제로 띄워서 페이지 소스를 확인해보면 보면 title 태그가 2개 정의되어 있는 것을 확인할 수 있다. 반면 2번 방법을 사용할 경우 페이지 컴포넌트에서 재정의한 title 태그 하나만 적용되어 있는 것을 확인할 수 있다.

 

결국 결합이냐 상속이냐 인데 공통헤더와 페이지헤더라는 2개의 영역으로만 구분되고 부모에 해당되는 공통헤더의 내용이 100% 적용되어야 하기 때문에 결합보다는 상속이 나아보인다. 이에 공통헤더 정의시에는 2번 방법을 사용하는게 적절해 보인다.

 

그렇다면 _document.jsx 는 대체 언제 어떻게 사용되는걸까? 흠...


_error.jsx 의 경우 예상했듯이 에러페이지로 에러가 발생할 경우 해당 컴포넌트가 랜더링된다. 에러페이지의 경우 이 외에 400.jsx 파일을 만들어놓으면 페이지를 찾을 수 없을 때에는 이 페이지를 호출하게 된다.

 

https://beside-lab.tistory.com/entry/Nextjs-App-Document-Error
https://simsimjae.tistory.com/424
http://52.78.22.201/tutorials/nextjs/nextjs-007/
https://nextjs.org/docs/messages/no-title-in-document-head

728x90