Custom Document
사용자 정의 Document
는 페이지를 렌더링하는 데 사용되는 <html>
및 <body>
태그를 업데이트할 수 있습니다.
기본 Document
를 오버라이드 하려면 아래와 같이 pages/_document
파일을 생성하세요.
pages/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
pages/_document.jsx
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
알아두면 유용한 정보
_document
는 서버에서만 렌더링되므로, 이 파일에서는onClick
과 같은 이벤트 핸들러를 사용할 수 없습니다.- 페이지가 제대로 렌더링되려면
<Html>
,<Head />
,<Main />
및<NextScript />
가 필요합니다.
Caveats
_document
에 사용된<Head />
컴포넌트는next/head
와 동일하지 않습니다. 여기에 사용된<Head />
컴포넌트는 모든 페이지에 공통으로 적용되는<head>
코드에만 사용해야 합니다.<title>
태그와 같은 다른 모든 경우에는 페이지 또는 컴포넌트에서next/head
를 사용하는 것이 좋습니다.<Main />
외부의 React 컴포넌트는 브라우저에서 초기화되지 않습니다. 여기에 애플리케이션 로직이나 커스텀 CSS(예:styled-jsx
)를 추가하지 마세요. 모든 페이지에 공유되는 컴포넌트(메뉴 또는 툴바)가 필요한 경우 레이아웃을 대신 참고하세요.Document
는 현재getStaticProps
또는getServerSideProps
와 같은 Next.js 데이터 패칭 메서드를 지원하지 않습니다.
Customizing renderPage
renderPage
커스터마이징은 고급 기술이며 서버 사이드 렌더링을 지원하기 위해 CSS-in-JS와 같은 라이브러리에서만 필요합니다. 내장된 styled-jsx
지원에는 필요하지 않습니다.
이 패턴을 사용하지 않는 것이 좋습니다. 대신 페이지와 레이아웃에 대한 데이터를 더 쉽게 가져올 수 있는 App Router를 점진적으로 도입하는 것을 고려하세요.
pages/_document.tsx
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
DocumentInitialProps,
} from 'next/document'
class MyDocument extends Document {
static async getInitialProps(
ctx: DocumentContext,
): Promise<DocumentInitialProps> {
const originalRenderPage = ctx.renderPage
// React 렌더링 로직을 동기적으로 실행합니다.
ctx.renderPage = () =>
originalRenderPage({
// 전체 React 트리를 래핑하는 데 유용합니다.
enhanceApp: (App) => App,
// 페이지별로 래핑하는 데 유용합니다.
enhanceComponent: (Component) => Component,
})
// 부모의 `getInitialProps`를 실행하며, 이제 커스텀 `renderPage`가 포함됩니다.
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
pages/_document.jsx
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage
// React 렌더링 로직을 동기적으로 실행합니다.
ctx.renderPage = () =>
originalRenderPage({
// 전체 React 트리를 래핑하는 데 유용합니다.
enhanceApp: (App) => App,
// 페이지별로 래핑하는 데 유용합니다.
enhanceComponent: (Component) => Component,
})
// 부모의 `getInitialProps`를 실행하며, 이제 커스텀 `renderPage`가 포함됩니다.
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
알아두면 유용한 정보
_document
의getInitialProps
는 클라이언트 측 전환 중에는 호출되지 않습니다._document
의ctx
객체는getInitialProps
에서 받은 것과 동일하며,renderPage
가 추가되어 있습니다.