강디너의 개발 일지

Next.js SEO를 위한 next/head 탐구 본문

Javascript/React.js

Next.js SEO를 위한 next/head 탐구

강디너 2022. 7. 30. 18:51
728x90

React.js에서 타이틀, 설명 등 SEO 구색을 어느 정도 맞추기 위해서는 react-helmet 이란 라이브러리를 사용합니다.

Next.js에서도 그럼 헬멧을 사용해야하나 ? 라는 의문에서 조사를 시작했습니다.

 

구글에서는 이제 SPA방식의 웹사이트도 어느 정도 크롤링 잘해주지만 특정 페이지의 title, og image 등을 바꾸기 위해 스크립트를 통해서 수정합니다. (카톡, 페이스북 공유 등.)

react-helmet 동작 방식

 

Next.js는 조금 다릅니다.

SSR 방식이기 때문에 굳이 렌더링 이후, 스크립트를 통해서 meta tag들을 바꾸지 않아도 됩니다.

렌더링 할 때 meta tag를 넣어서 렌더링 해주면 되기 때문입니다.

 

 

Next.js에서는 편리하게  지정할 수 있도록 next/head 라고 지원해줍니다. 공식문서

 

아래 코드는 API에서 받아온 데이터를 이용해서 meta tag에 title을 동적으로 넣었습니다.

export const getServerSideProps: GetServerSideProps = async ({ params }) => {
  const result = await fetchPost(params?.id as string);

  return {
    props: result,
  };
};

const Posts: NextPage<PostProps> = ({
  contentHtml,
  title,
  date,
}) => {
  return (
    <>
      <Head>
        <title>{ title }</title>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      </Head>
      <div>
        <h2>{ title }</h2>
        <p> { date }</p>
        <span dangerouslySetInnerHTML={{ __html: contentHtml }}></span>
      </div>
    </>
  );
};

 

이건 특정 페이지에 메타 태그를 수정한 방법입니다.

모든 페이지에 각각 넣어야한다면 매우 불편하겠죠???

방법이 다 있습니다.

 

custom document라는 것을 이용해서 전역 meta tag를 지정할 수 있습니다. 공식문서

(create-next-app으로 만들었는데, _document가 없어서 생성했습니다.)

 

_app 은 가장 먼저 실행되는 컴포넌트입니다.

  • 공통 레이아웃, global css 등 페이지에 적용할 공통 속성을 적용하는 컴포넌트.

 

_document는 HTML Document를 커스텀할 때 사용합니다.

  • 웹 접근성 관련 태그 설정(메타 태그 등)
  • head, body 등을 커스터마이징 할 때 사용

주의사항으로는 head를 설정할 때 next/document의 Head를 사용해야 합니다.

 

_app.tsx -> 해당 페이지 -> _document.tsx 순서로 렌더링 됩니다. (_app 다음에 _document가 렌더링 되는 줄 알았는데..)

 

 

그러면 저희는 메타 태그를 설정하기 위해서 _document를 커스터마이징 해야겠죠??

import { Html, Head, Main, NextScript } from 'next/document'

const Document = () => {
  return (
    <Html lang="ko">
      <Head>
        <meta name="description" content="Document의 메타태그" />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

export default Document;

 

전역 메타 태그가 잘 설정되어있는 것을 볼 수 있습니다.

 

여기서 궁금증 !

만약 전역에서 메타 태그를 선언하고, 각 페이지에서 해당 메타 태그를 중복으로 선언하면 어떻게 될까 궁금하지 않으신가요 ?

title을 전역에 한번 설정해보려고 했는데,,,

타이틀은 Page에서 사용하라고 알려주네요 !

 

description을 중복으로 넣어봤습니다.

각 페이지 -> _document 순으로 렌더링 되기 때문에 전역의 description이 overide 될 것 같아 보입니다.

const Posts: NextPage<PostProps> = ({
  id,
  contentHtml,
  title,
  date,
}) => {
  return (
    <>
      <Head>
        <title>{ title }</title>
        <meta name="description" content={`${title}이 들어가있어요`} />
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      </Head>
      <div>
        <h2>{ title }</h2>
        <p> { date }</p>
        <span dangerouslySetInnerHTML={{ __html: contentHtml }}></span>
      </div>
    </>
  );
};

 

하지만 예상을 깨고 그냥 두 번 선언되는 것을 볼 수 있습니다.

나중에 크롤링하게 되면 어떤 것을 보여줄지는 잘 모르겠네요. (먼저 선언된 것을 읽으려나...)

 

 

참고 글

_app.tsx 와 _documents.tsx

Next.js _document _app 대하여

반응형
Comments