react-helmet으로 페이지별 SEO 메타태그 설정하기

리액트는 SPA이라, 각 검색로봇(크롤러)들이 리액트로 만들어진 사이트를 읽을 때 단 하나의 public/index.html 만을 읽게 된다. 이는 각각의 페이지에 대한 정보를 읽지 못한다는 단점이 있다.

이러한 SPA의 단점을 극복하기 위해 나왔다는 react-helmet 라이브러리를 찾아보았다. 나는 서버사이드렌더링을 따로 설정할 수 없고, jsx를 사용하는 환경에 있기 때문에, 이 라이브러리를 사용하면 페이지별 메타태그를 다르게 정의할 수 있음을 직감하고 바로 삽질을 시작했다.

우선 검색엔진최적화(SEO)가 왜 중요한지에 대해 서술하자면,

우리 회사 사이트를 검색결과에서 가장 상위에 위치시키려면 html 시멘틱 태그를 사용하는 등 다양한 방법이 있다. 그중에서도 가장 확실한 방법은 크롤러가 읽기 쉽도록 메타태그를 설정하여 사이트 정보를 제공하는 것이다.

또한 각각 페이지의 정보를 메타태그로 무슨 페이지인지 설명해 주어야, 우리 회사 사이트 안에 있는 페이지들을 원활하게 수집할 수 있다. 수집한 페이지가 많으면 많을수록 검색엔진최적화 점수(이해하기 쉽게 썼습니당.)가 높아지고, 검색결과에 여러 개의 페이지들이 등록이 된다. 사용자 입장에서는 일단 검색한 회사 사이트의 페이지가 많으니, 그 페이지를 이것저것 눌러볼 수 있겠다. 등록된 페이지가 많으면 많을수록 클릭율도 점차 높아질 테니, 우리 회사 사이트는 인기 있는 사이트라고 인식되어 (클릭율이 상대적으로 저조한) 타 사이트를 제치고 점점 상위로 랭크 될 것이다.

결론은, 사이트에 대한 디폴트 설명이 있는 메타태그페이지별 메타태그를 구분지어 정의할 수 있어야 된다는 것이다.


작업 순서

1. react-helmet-async 설치

$ yarn add react-helmet-async

2. 감싸주기

  1. <App /><HelmetProvider>로 감싸준다.
  • Helmet 컴포넌트는 HelmetProvider 컴포넌트 안에 있어야 하기 때문이다.
// Index.js
import { HelmetProvider } from 'react-helmet-async';

ReactDOM.render(
  <Provider store={store}>
    <BrowserRouter>
      <HelmetProvider>
        <App />
      </HelmetProvider>
    </BrowserRouter>
  </Provider>,
  document.getElementById(‘root‘),
);
  1. 디폴트 메타태그를 App.js에 <Helmet> ~ </Helmet>으로 정의한다.
// App.js
import { Helmet } from 'react-helmet-async';

const App = () => {
  return (
    <>
      <Helmet>
        <title>REACTERS</title>
      </Helmet>
      <Route component={} path={} exact />
      <Route component={} path={} exact />
    </>
  );
};
  1. 페이지별 메타태그는 각 페이지 컴포넌트 파일 안에 <Helmet> ~ </Helmet>으로 정의할 예정이다.

    react-helmet-async에서는 더 깊숙한 곳에 위치한 Helmet이 우선권을 차지합니다. >> 더보기 링크 <<

3. 만약 index.html에 SEO 메타태그가 이미 정의되어 있다면?

중복 방지를 위해 제거해야 한다.

index.html에 메타태그가 이미 정의되어 있는데, App.js에 Helmet으로 메타태그를 정의하게 되면 똑같은 중복 태그가 두 개 있는 셈이다.

4. MetaTag.js 파일로 메타태그 관리하기

위의 2-2번의 디폴트 메타태그와, 페이지별로 메타태그를 정의를 해야 되는 상황이다.

<Helmet>
  <title>React Title</title>
  <meta name="description" content="나만 알고 싶은 코스메틱 향기 브랜드 - 비누, 천연, 스프레이드" />
  <meta property="og:image" content="" />
  <meta property="og:url" content="" />
</Helmet>

위처럼(예시입니당) 길이가 긴 메타태그를 컴포넌트 파일에 정의를 여러 번 해야 되다 보니, 차라리 메타태그 전용 파일 하나를 따로 만들고 선언하여 쓰면 관리가 편할 것 같았다.

아래에 메타태그 전용 관리 파일을 나름 정의해 보았다. 추후 props의 존재 유무에 따라, 디폴트와 페이지별 메타태그를 따로 구분하여 추가할 예정이다.

// SEOMetaTag.js
import React from 'react';
import { Helmet } from 'react-helmet-async';

const MetaTag = props => {
  // props로 content 내용을 불러올 예정임
    return (
      <Helmet>
        <title>{props.title}</title>

        <meta name="description" content={props.description} />
        <meta name="keywords" content={props.keywords} />

        <meta property="og:type" content="website" />
        <meta property="og:title" content={props.title} />
        <meta property="og:site_name" content={props.title} />
        <meta property="og:description" content={props.description} />
        <meta property="og:image" content={props.imgsrc} />
        <meta property="og:url" content={props.url} />

        <meta name="twitter:title" content={props.title} />
        <meta name="twitter:description" content={props.description} />
        <meta name="twitter:image" content={props.imgsrc} />

        <link rel="canonical" href={props.url} />
      </Helmet>
    );
};

export default MetaTag;
// App.js
import SEOMetaTag from './pages/MetaTag';
//import { Helmet } from 'react-helmet-async';

const App = () => {
  return (
    <>
      <SEOMetaTag />
      <Route component={} path={} exact />
      <Route component={} path={} exact />
    </>
  );
};

5. 페이지 이동시 title만 바뀌는 경우

이것저것 시도를 해보면서 각 다른 페이지에 접속시, <title>만 바뀌고 다른 메타태그의 content는 변경이 되지 않는 이슈가 있었다. (스택오버플로우에 나랑 같은 경험을 한 분이 계시더라..)

해결 방법으로는 data-react-helmet="true" 속성을 추가해 보는 방법이 있다.

<meta name="description" content={props.description} data-react-helmet="true" />

위와 같은 이슈는, 나의 경우에 react-helmet 라이브러리를 썼을 때 발생했었다. react-helmet-async 라이브러리로 갈아타니까, data-react-helmet="true" 위 속성을 따로 추가하지 않아도 무엇인가가 자동으로 생기더라.

아래 캡처는 개발자도구의 <head>에서 본 메타태그이다. data-rh="true" 속성이 자동으로 생김. 굳👍

좋은 웹페이지 즐겨찾기