[Culture Place제작기-2-] Nextjs, SPA도 SEO 최적화가 되요? getStaticProps, getServerSideProps, getStaticProps

column clash·2021년 9월 28일
3

NextJs 를 사용하는 가장 큰 이유는, 결국 seo 친화적인
싸이트를 만들기 위해서다.

SEO 는 쉽게 말해서, 구글과 네이버에서 검색엔진이
잘 찾아주는 싸이트냐인데,

개발자에게도 중요하지만, 좀 더 확장적으로 마케터나
사업자로써 본다면, SEO 는 상당히 중요한 개념으로써

우리가 "컨텐츠 마케팅이나, 퍼포먼스 마케팅"도 해야하지만
SEO 가 더 해져야 여러모로 우리하다고 할 수 있는데,

REACT 의 단점으로는 이런 SEO 적용이 상당히
불편하게 되어있고 별다른 설정없이는
SEO 에 매우 불리하다는 데 있다.

SEO 전문가를 따로 고용하는 회사들도 상당수 있기때문에
SEO 의 중요성은 두말하면 잔소리고, 쉽게 말해,
네이버 블로그에서 저품질 블로그마냥 SEO 를 제대로
안하면 이런 싸이트가 된다는 것이다.

NEXTJS 의 다른 장점들도 많지만, 무엇보다 이 SEO 를
매우 편리하게 해주는 SSG, SSR 기능, 그리고 PAGE 단위의 라우팅이 가능한 시스템이 NEXTJS 의 핵심 기능 중 핵심기능이라 할 수 있다.

SSG 는 HTML 을 미리 빌드해서 STATIC 하게 보여주는 것이고, (바뀌지 않을 내용들)

SSR 은 상세페이지, 그래프 차트등 새롭게 데이터를
받아와야하는 곳에 쓰인다.

크롬 자바스크립트 기능을 disable 하고 다음을 테스트 해보자.

크롬 자바스크립트 기능 끄는 방법

일반적 api 처럼 axios 가 받아서 뿌려주는 방식

  1. index.tsx
import Link from "next/link";

export default function Index() {
  return (
    <div className="App">
      <Link href="/Test">
        <a>Test 페이지로 이동</a>
      </Link>
    </div>
  );
}
  1. Test.tsx
import React, { useEffect, useState } from "react";
import axios from "axios";

const Test = () => {
  const [list, setList] = useState([]);

  useEffect(() => {
    const getList = async () => {
      const { data } = await axios.get(
        `https://jsonplaceholder.typicode.com/posts`
      );

      console.log(data);
      setList(data);
    };
    getList();
  }, []);

  return (
    <div>
      <h1>Test</h1>
      {list.length &&
        list
          .slice(0, 10)
          .map((item: { id: number; title: string }) => (
            <li key={item.id}>{item.title}</li>
          ))}
    </div>
  );
};

export default Test;

결과는 "자바스크립트" 를 disabled 했기때문에,
0 이 된다.

SSG 를 만들어주는 getStaticProps

indext.tsx 는 그대로 두고,
test.tstx 만 바꿔보자.

import React, { useEffect, useState, FC } from "react";
import { GetStaticProps } from "next";
import axios from "axios";

interface Props {
 list: { id: number; title: string }[];
}

const SsgTemplate = ({ list }: Props) => {
 return (
   <div className="About">
     <h1>Test</h1>
     {list.length &&
       list.slice(0, 10).map((item) => <li key={item.id}>{item.title}</li>)}
   </div>
 );
};

export default SsgTemplate;

export const getStaticProps: GetStaticProps = async () => {
 const { data } = await axios.get(
   `https://jsonplaceholder.typicode.com/posts`
 );
 
  console.log(data[1]);

 return {
   props: {
     list: data,
   },
 };
};

그리고 크롬의 자바스크립트는 disabled 로 두자.
리스트가 제대로 나타나는 것을 확인했다.
단, constole.log 는 찍히지 않았다.

즉, 일반 api 불러오듯 하면,
SEO 기능이 최적화가 되지 않고, SSG 시에는
SEO 기능이 최적화 될 수 있음을 우리는 예측할 수 있다.
다만, 자바스크립트 기능이 비활성화 됨을 알 수 있다.

이제 SSR 을 테스트 하자. getServerSideProps

루트 폴더에 ssr 폴더 하나를 생성하고,
[id].tsx 파일 하나를 생성한다. (다이나믹 라우터 기능을 위해)

ssg.tsx 파일을 다음과 같이 변경한다.

import React, { useEffect, useState } from "react";
import { GetStaticProps } from "next";
import Link from "next/link";
import axios from "axios";

interface Props {
  list: { id: number; title: string }[];
}

const SsgTemplate = ({ list }: Props) => {
  return (
    <div className="About">
      <h1>Test!</h1>
      {list.length &&
        list.slice(0, 10).map((item) => (
          <li key={item.id}>
            <Link href={`ssr/${item.id}`}>{item.title}</Link>
          </li>
        ))}
    </div>
  );
};

export default SsgTemplate;

export const getStaticProps: GetStaticProps = async () => {
  const res = await axios.get(`https://jsonplaceholder.typicode.com/posts`);
  const data = res.data;

  console.log(data[1]);

  return {
    props: {
      list: data,
    },
  };
};

클릭하면, ssr의 해당 id 로 이동하게 만들었다.

ssr/[id].tsx

import React, { useEffect, useState, FC } from "react";
import { GetServerSideProps } from "next";
import axios from "axios";

interface Props {
  item: { title: string; body: string; id: number };
}

const SsrTemplate = ({ item }: Props) => {
  return (
    <div className="Detail">
      <h1>{item.title}</h1>
      <p>{item.body}</p>
      <p>{item.id}번째 게시글</p>
    </div>
  );
};

export default SsrTemplate;

export const getServerSideProps: GetServerSideProps = async (ctx) => {
  const id = ctx.params?.id;
  const res = await axios.get(
    `https://jsonplaceholder.typicode.com/posts/${id}`
  );

  const data = res.data;

  console.log(data);

  return {
    props: {
      item: data,
    },
  };
};

자바스크립트 disable 을 하더라도,
결과 : 화면에 타이틀과 body, id 에 해당 text 들이
잘 렌더링 될뿐 아니라,

console.log(data); 도 잘 동작하는 것을 확인할 수 있다.

이제 마지막으로, getStaticPaths 을 익혀보자.

다이나믹 라우터를 이용하더라도, ssg 를 활용하고
싶을 수 있다. 이때 getStaticPaths 를 활용하면 된다.

pathTemplate 폴더를 하나 생성하고,
[id].tsx 파일을 하나 생성해서 다음을 copy+paste 해보자.

import React from "react";
import { GetStaticProps, GetStaticPaths } from "next";
import axios from "axios";

interface Props {
  item: { title: string; body: string; id: number };
}

const pathTemplate = ({ item }: Props) => {
  return (
    <div>
      {item && (
        <div className="Detail">
          <h1>{item.title}</h1>
          <p>{item.body}</p>
          <p>{item.id}번째 게시글</p>
        </div>
      )}
    </div>
  );
};

export default pathTemplate;

export const getStaticPaths: GetStaticPaths = async () => {
  return {
    paths: [
      { params: { id: "1" } },
      { params: { id: "2" } },
      { params: { id: "3" } },
      { params: { id: "4" } },
      { params: { id: "5" } },
    ],
    fallback: true, // --> false 시 1,2,3외에는 404
  };
};

export const getStaticProps: GetStaticProps = async (ctx) => {
  const id = ctx.params?.id;
  const res = await axios.get(
    `https://jsonplaceholder.typicode.com/posts/${id}`
  );

  const data = res.data;

  return {
    props: {
      item: data,
    },
  };
};

getStaticPaths 에서 paths 를 통해 미리 ssg 페이지를
만들어낼 수 있고,

fallback 옵션에 따라, 그 외 다이나믹 라우트로
들어온 경우 false 는 404 페이지를 보여주고,
true 만 ssg 페이지를 하나 더 만들어주는 것을 확인할
수 있다.

(확인을 위해선 생성된 .next 폴더의 server/pages 폴더를 확인해보자.)

fallback 옵션을 주지 않으면 기본 true 상태로
prefetch 기능이 활성화 된다.

첫 렌더링시 뷰포트에 보이는 목록 또는 스크롤 하여
랜더링 되는 목록들은 next/link 가 prefetch 하여
ssg 페이지들이 생성된다.

결론 : NEXTJS 를 사용하는 이유는 SEO. 그냥 API 부르듯 사용하지 말고, SSG 나 SSR 기능을 활용해서 제작하도록 한다.

다이나믹 라우터가 아닌 경우, SEO => SSG
다이나믹 라우터를 사용하는데, 어느정도 정해진 상품군 => getStaticPaths
차트나, 변화가 심한 경우 => SSR 을 사용하면 될듯 하다.


SEO 기능은
META 설정등이 중요하기때문에,
추후 NEXT-SEO 라이브러리를 소개해 추가하도록 하겠다.
(SPA 용 sitempa 제네레이션과 네이버, 구글에 등록하는 것도
차차 블로그에 올리겠다)

( SEO 는 백링크나 싸이트 유입량, 체류랑에도 영향을 받기때문에 방금 소개한, SSG, SSR 만이 전부는 아니다.

SSG 나 SSR 은 의미에 맞는 마크업을 하는 것이
SEO 에 영향을 미치는 것과 비슷한 영향을 미친다 할
수 있을 것이다.)

구글등의 검색엔진은 SPA 도 잘 해석하고 있고,
마인드케어센터도 잘 노출되고 있다.

네이버 검색엔진도 SPA 가 잘된다고 하고,
마인드케어센터도 잘 나오기는 하지만
아직 많은 사람들이 네이버 검색엔진의 성능을
제대로 믿지 못하고 있으므로, SSG 나 SSR 로
로봇이 잘 읽을 수 있는 환경등을 만들자.

profile
풀스택 개발 중...

0개의 댓글