Next.js SSR, getServerSideProps 사용하기

백우진·2023년 3월 7일
3

Next.js는 더 나은 성능SEO를 위해서 페이지를 미리 랜더링하는데 대표적으로 getServerSidePropsgetStaticProps가 있다. 이번 시간에는 getServerSideProps에 대해서 자세히 다뤄보자.


getServerSideProps

  • 서버 사이드 랜더링(SSR) 방식
  • 서버 측에만 실행되고 브라우저에서는 실행되지 않음
  • 외부 데이터를 서버에서 받아와 초기 데이터로 설정하고 페이지로 전달
  • 페이지 요청마다 실행
  • 동적으로 데이터를 가져와 업데이트가 가능하다는 장점

언제 사용할까?

  1. 동적인 데이터가 필요한 경우
    사용자의 로그인 상태, 쇼핑카드 내용등과 같이 페이지가 랜더링 될 때마다 바뀌는 데이터가 있는 경우

  2. 검색 엔진 최적화(SEO)를 고려하는 경우
    서버 측에서 데이터를 미리 가져오므로, 검색 엔진이 페이지의 콘텐츠를 분석할때 초기 데이터가 포함되어 SEO에 유리

  3. API를 통해 데이터를 가져오는 경우
    클라이언트 측에서 호출하면 CORS문제가 발생 할 수 있는데 getServerSideProps를 사용하면 문제를 방지 할 수 있다


기본 형태

export async function getServerSideProps(context) {
  // 데이터를 가져오는 비동기 함수
  // ...
  
  return {
    props: {
      // 데이터 객체
      // ...
    }
  }
}
  • context : Next.js에서 제공하는 컨텍스트 객체로 현재 요청 정보와 함께 페이지에 필요한 다양한 데이터를 가져오는데 사용한다.
  • getServerSideProps 함수에서는 필요한 데이터를 가져온 다음 props 객체에 담아 리턴한다.


프로젝트 적용 전

  • 선수 정보를 보여주는 화면

  • 페이지가 랜더링되기 전에 가져오는 정보가 없다
// 코드

import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { getStandingByYear } from "@/apis/api/seasons";
import * as S from "@/styles/year.style";
import DriverCard from "@/components/card/driverCard";

export default function Year() {
  const [result, setResult] = useState(null);
  const [loading, setLoading] = useState(true);
  const router = useRouter();
  const { year } = router.query;

  useEffect(() => {
    if (year) {
      getStandingByYear(Number(year)).then((res) => {
        setResult(res);
        setLoading(false);
      });
    }
  }, [year]);

  if (loading) {
    return <div>로딩중...</div>;
  }

  return (
    <S.CardContainer>
      {result.map((driver, index) => (
        <DriverCard key={index} driver={driver} />
      ))}
    </S.CardContainer>
  );
}
  • 클라이언트 단에서 axios 요청을 통해 데이터를 받고 state에 저장을 해 map을 통해 선수 정보를 보여주는 화면이다.
  • API를 호출하고 있고, SEO최적화를 고려해보고자 getServerSideProps를 적용해본다.

프로젝트 적용 후

import * as S from "@/styles/year.style";
import DriverCard from "@/components/card/driverCard";
import Axios from "axios";
import Head from "next/head";

export default function Year({ drivers }) {
  return (
    <S.CardContainer>
      <Head>
        <title>{drivers[0].Driver.familyName}</title>
        <meta name="nationality" content={drivers[0].Driver.nationality}></meta>
      </Head>
      {drivers &&
        drivers.map((driver, index) => (
          <DriverCard key={index} driver={driver} />
        ))}
    </S.CardContainer>
  );
}

export async function getServerSideProps(context) {
  const { year } = context.query;
  const apiUrl = `https://ergast.com/api/f1/${year}/driverStandings.json`;
  const res = await Axios.get(apiUrl);
  const data = res.data.MRData.StandingsTable.StandingsLists[0].DriverStandings;
  return {
    props: {
      drivers: data,
    },
  };
}
  • getServerSideProps 생성
  • context.query를 이용 === next/router의 useRouter
  • 데이터를 가져온 뒤 props 데이터 객체에 담아 리턴
  • 메인 컴포넌트에서 props로 사용
  • SEO를 위한 <HEAD>, <title>, <meta> 설정

  • title, nationality 설정완료

getServerSideProps 를 한번 프로젝트에 적용 해 보았다.
적용을 해 보니 SEO를 위해서는 쇼핑몰 상세페이지가 적합할 것 같다는 생각을 했다.

profile
안녕하세요.

0개의 댓글