커스텀 도큐먼트 컴포넌트는 우리가 이전에 만든 커스텀 앱 컴포넌트와 비슷합니다. 커스텀 앱 컴포넌트는 NextJS가 앱을 빌드할 때, 앱 전체의 청사진과 같은 기능을 했습니다.
반면에 도큐먼트 컴포넌트를 이용하면 body태그도 변경할 수 있고, html태그도 수정할 수 있습니다. 그리고 이 컴포넌트 안에서 SEO는 어떻게 적용하는지, 그리고 NextJS가 폰트 최적화를 어떻게 대신해주는지 간단히 알아보도록 하겠습니다.
https://nextjs.org/docs/advanced-features/custom-document
우선 위 공식문서를 참고하여 작성해보도록 하겠습니다.
커스텀 document페이지는 기존의 작성된 'next/document'의 Document컴포넌트를 상속받습니다. 이를 저는 일단 legacy로 class형 컴포넌트로 작성해 주도록 하겠습니다.
/pages/_document.tsx
// import { Html, Head, Main, NextScript } from "next/document";
import Document, {
Head,
Html,
Main,
NextScript,
} from "next/document";
class CustomDocument extends Document {
render(): JSX.Element {
console.log("DOCUMENT IS RUNNING");
return (
<Html lang="ko">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default CustomDocument;
/pages/_app.tsx
import "../styles/globals.css";
import type { AppProps } from "next/app";
import { SWRConfig } from "swr";
import useUser from "@libs/client/useUser";
import { useRouter } from "next/router";
function MyApp({ Component, pageProps }: AppProps) {
const { pathname } = useRouter();
const { user } = useUser(pathname);
console.log("APP IS RUNNING");
return (
<SWRConfig
value={{
fetcher: (url: string) =>
fetch(url).then((response) => response.json()),
}}
>
<div className="mx-auto w-full max-w-xl">
<Component {...pageProps} />
</div>
</SWRConfig>
);
}
export default MyApp;
여기서 주의해야 할 점이 있습니다. _app.tsx는 클라이언트 사이드에서 모든 페이지의 청사진의 역할을 한다고 했습니다. 그래서 서버사이드와, 클라이언트 사이드에서 매 페이지가 렌더링될 때마다 실행되는 것이 특징입니다. 다만 _document.tsx은 NextJS앱의 Html뼈대를 짜주는 역할을 합니다. 따라서 공식문서에서도 명시되어 있는데, 서버에서 단 한번 실행된다고 되어 있습니다. 따라서 Browser API를 여기에다 때려박으면 당연히 오류가 납니다.
커스텀 도큐먼트 파일이 잘 작동하는 것을 확인해볼 수 있습니다.
그 외에도 _document.tsx는 폰트 최적화도 자동으로 해줍니다. 이는 빌드타임에만 최적화 해주므로 일단 구글 폰트에서 Noto Sans폰트를 다운받고 stylesheet link태그를 아래와 같이 커스텀 도큐먼트의 헤더 안에 작성해 주었습니다.
/pages/_document.tsx
// import { Html, Head, Main, NextScript } from "next/document";
import Document, {
Head,
Html,
Main,
NextScript,
} from "next/document";
class CustomDocument extends Document {
render(): JSX.Element {
console.log("DOCUMENT IS RUNNING");
return (
<Html lang="ko">
<Head>
<link
href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap"
rel="stylesheet"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default CustomDocument;
개발 환경에서 이가 어떻게 적용되고 폰트를 어떻게 다운받는지 확인해 보도록 하겠습니다.
이렇게 googleapis에서 font를 다운받고 그 안에서 src로 폰트파일을 다운받는 것을 확인해 볼 수 있습니다.
그렇다면 빌드하고 index.html파일을 들여다 보겠습니다.
그냥 싹다 <link>태그를 없애고 <style>태그를 만들고 그 안에다가 다운받은 폰트들을 싹다 적어서 폰트 최적화를 진행했습니다. 따라서 유저는 폰트가 어디있는지 알려주는 파일을 다운로드 받지 않아도 되므로 폰트를 로딩없이 사용이 가능해지는 겁니다.
'Web > NextJs' 카테고리의 다른 글
[ Next.js - DeepDive ] - getServerSideProps (0) | 2022.08.06 |
---|---|
[ Next.js - DeepDive ] - Script Component (0) | 2022.08.06 |
[ Next.js - DeepDive ] - Lazy-load Imports (0) | 2022.08.04 |
[ Next.js - DeepDive ] - Dynamic Import (0) | 2022.08.04 |
[ Next.js - DeepDive ] - Responses and Redirections (0) | 2022.08.04 |