공부

[React] 검색엔진 최적화(SEO)

hahihuree 2021. 9. 30. 17:38

React는 SPA로 HTML이 하나이며, CSR(클라이언트 사이드 렌더링)을 하기 때문에 렌더링(자바스크립트 실행)이 되기 전까지는 껍데기 HTML만 나오므로 검색 엔진 최적화가 어려움.

 

  meta tag  

  • HTML의 head부분에 있는 <meta>를 활용. 
  • React는 정적 페이지가 index.html 하나이므로 페이지별로 메타태그를 적용하려면 라이브러리 사용.
  • 라이브러리 react-helmet 설치. (yarn add react-helmet)
  • 적용하고 싶은 페이지로 가서 Helmet import하고, <Helmet>안에 child로 넘겨주고 싶은 메타태그 작성.
  • // 예시
    const One = () => {
    	return (
        	<>
                <Helmet>
                	<title>page one</title>
                    <meta property="og:title" content="og page one"/>
                    <meta property="og:description" content="hello"/>
                    <meta property="og:image" content="이미지링크"/>
                </Helmet>
            </>
        )
    }

 

  pre-rendering  

  • 빌드 시 미리 특정 페이지를 렌더링 해서 html파일을 만들어 두는 것.
  • 프로젝트에 바로 붙이지 말고 새 프로젝트를 만들어 사용할 것. (yarn create react-app 새프로젝트이름)
  • react-snap과 react-router-dom 설치. (yarn add react-router-dom, yarn add --dev react-snap)
  • 페이지 만들고 라우트 적용 후 yarn start해서 작 적용되었나 확인.
  • package.json 가서 scripts아래에 "postbuild": "react-snap" 및 어떤 경로를 추가할지 작성.
  • // 예
    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject",
        "postbuild": "react-snap"
      },
    ...
    "reactSnap": {
        "include": [
          "/two",
          "/"
        ]
      },
      ...
  • index.js 가서 기존 코드 주석처리 하고 아래 코드 삽입.
  • // 예
    import React from 'react';
    import ReactDOM, { hydrate } from "react-dom";
    ...
    
    const root = document.getElementById("root");
    
    if (root.hasChildNodes()) {
      hydrate(
          <App />,
        root
      );
    } else {
      ReactDOM.render(
        <App />,
        root
      );
      ...
    }​
     
  • 결과물 확인
    •  yarn build
    • 빌드한 프로젝트 로컬에서 실행
      1. package.json과 같은 위치에 serve.json파일 만들고 아래 코드 삽입. (소스는 프젝에 따라 변경)
      2. {
          "rewrites": [
          // "/"경로로 들어오면 "/200.html"을 보여줌(경로 잡아준 것)
            { "source": "/", "destination": "/200.html" },
            { "source": "/two", "destination": "/two/index.html" }
          ]
        }
      3. yarn global add serve
      4. serve -c serve.json build (serve.json 설정을 가지고 빌드에 있는 내용물을 실행함)
      5. build하고 postman으로 html내용 들어가는지 확인

* react-dom의 hydrate

- pre-rendering을 하는 것은 컴포넌트 트리를 그대로 가져가는게 아니고, html DOM을 index.js에 넣는 것.

- 이는 React의 컴포넌트가 아닌 DOM객체 일 뿐이라 React스럽게 쓸 수가 없음.

- 이에 따라 hydrate는 React의 컴포넌트로 쓸 수 없는 곳에 이벤트를 주입해 줌.

- hasChildNodes 라는 것은 자식 노드들이 있다는 것이고, 이는 미리 내용물이 들어가 있다는 뜻.

 

* 프로젝트에 바로 붙이지 말라는 이유

- react-snap은 firestore에서 요청하고 받아오는 정보를 읽을 줄 모름.

- firestore에서는 프리렌더링을 못하나?

- REST API방식으로 주고 받을 수 있지만, 데이터 구조를 다시 짜야 함.

- 즉, firestore를 사용하고 프리렌더링을 하려면 데이터 구조 먼저 잡고 시작해야 함.

 

  SSR  

  • Next.js 라이브러리 사용.
  • react-router와 loadable-component로 code-splitting 하기.

 

 

 

 

참고 https://github.com/stereobooster/react-snap

참고 https://mygumi.tistory.com/385